javascript object __count__ property

XPCNativeWrapper – MDCの保護対象に__count__プロパティというのが入っていて、これがなんなのかの解説が日本語で見当たらなかったのでちっょと調べてみました。

何のために使うのかわかりませんが、基本はオブジェクトが持っているプロパティの数を返します。

( {name: "ku", value: "ma"} ).__count__

を評価すると2になります。

コードをちらっと見るとmozilla/js/src/jsobj.cjs_Enumerateがそれっぽくて

    switch (enum_op) {
      case JSENUMERATE_INIT:
        if (!enumerate(cx, obj))
            return JS_FALSE;
        length = 0;

        /*
         * The set of all property ids is pre-computed when the iterator
         * is initialized so as to avoid problems with properties being
         * deleted during the iteration.
         */
        JS_LOCK_OBJ(cx, obj);
        scope = OBJ_SCOPE(obj);

        /*
         * If this object shares a scope with its prototype, don't enumerate
         * its properties.  Otherwise they will be enumerated a second time
         * when the prototype object is enumerated.
         */
        proto = OBJ_GET_PROTO(cx, obj);
        if (proto && scope == OBJ_SCOPE(proto)) {
            ida = js_NewIdArray(cx, 0);
            if (!ida) {
                JS_UNLOCK_OBJ(cx, obj);
                return JS_FALSE;
            }
        } else {

とか書いてあ。

        if (proto && scope == OBJ_SCOPE(proto)) {

__proto__のスコープが違うとなにか違いがあるらしいのでちょっと実験してみました。


var s = {
value: "hi",
length: 2
};
s.__proto__ = {classname: "string"};

for ( var i in s ) {
 console.log(i);
}
console.log(s.__count__);

そうすると出てくる結果は

value
length
classname
2

このとおり。自分自身のクラスが持ってるプロパティだけが数として帰ってくるみたいです。

ただしいっしょに

deprecated __count__ usage

というwarningも出るので注意。

これでたぶんprototypeの汚染を調べることができます。
prototype.jsを読み込んでいない場合は

var a  = new Array();
a.__proto__.__count__

が0ですが、prototype.jsはFirefoxでしか使えない__proto__を使わずにいろんなメソッドを追加しているので、prototype.jsを読み込んでいるとこの値が31になります(1.4.0_rc4の場合)。


About this entry