24

JavaScriptには、配列のふりをする(または「配列のような」)オブジェクトがあります。このようなオブジェクトはarguments、、NodeLists(などから返されるgetElementsByClassName)、およびjQueryオブジェクトです。

古くなるとconsole.log、それらは配列として表示されますが、そうではありません。配列のようになるには、オブジェクトにlengthプロパティが必要であることを私は知っています。

だから私はこのような「オブジェクト」を作りました:

function foo(){
    this.length = 1;
    this[0] = "bar";
}

var test = new foo;

私がいるときconsole log(test)、私は(予想通り)fooオブジェクトを取得します。を使用して配列に「変換」できます

Array.prototype.slice.call(test)

しかし、私はそれを変換したくありません、私はそれを配列のようにしたいのです。配列のようなオブジェクトを作成して、古くなったときにconsole.log配列として表示されるようにするにはどうすればよいですか?

設定しようとしましfoo.prototype = Array.prototypeたが、配列ではなくオブジェクトがconsole.log(new foo)表示されます。foo

4

6 に答える 6

33

特にコンソールに依存します。Chrome の開発者コンソールのカスタム オブジェクトと Firebug には、 プロパティlengthspliceプロパティの両方が必要です。spliceも関数でなければなりません。

a = {
    length: 0,
    splice: function () {}
}
console.log(a); //[]

ただし、公式の基準がないことに注意することが重要です。

次のコードは、jQuery (v1.11.1) によって内部的に使用され、オブジェクトがループを使用するforかループを使用するかを決定しfor..inます。

function isArraylike( obj ) {
    var length = obj.length,
        type = jQuery.type( obj );

    if ( type === "function" || jQuery.isWindow( obj ) ) {
        return false;
    }

    if ( obj.nodeType === 1 && length ) {
        return true;
    }

    return type === "array" || length === 0 ||
        typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}

コンソールに配列として表示されるオブジェクト ( ) がjQuery[]のループで反復されるか、コンソールにオブジェクトとして表示されるオブジェクト ( ) がループで反復されるオブジェクトを持つことができることに注意してください。 jQueryで。for..in{}for

于 2012-08-09T15:19:59.343 に答える
3

これはどんな用途ですか:拡張配列プロトタイプ、彼はあなたがしたことをやっていて、プロトタイプを配列として作成しているようですが、追加のメソッドが含まれています(これは機能する場合と機能しない場合があります、私はこれをテストしていません):

var MyArray = function() {
};

MyArray.prototype = new Array;

MyArray.prototype.forEach = function(action) {
    for (var i = 0, l=this.length; i < l, ++i) {
        action(this[i]);
    }
};

それが何らかの形で役立つことを願っています。

于 2012-08-09T15:21:38.437 に答える
2

これを見てください:

var ArrayLike = (function () {

 var result;

 function ArrayLike(n) {

     for (var idx = 0; idx < n; idx++) {
         this[idx] = idx + 1;
     }

     // this.length = Array.prototype.length; THIS WILL NOT WORK !

 }


 // ArrayLike.prototype.splice = Array.prototype.splice; THIS WILL NOT WORK !


 // THIS WILL WORK !
 Object.defineProperty(ArrayLike.prototype, 'length', {

     get: function() {

         var count = 0, idx = 0;

         while(this[idx]) {
             count++;
             idx++;
         }
         return count;

     }

 });


 ArrayLike.prototype.splice = Array.prototype.splice;


 ArrayLike.prototype.multiple = function () {

     for (var idx = 0 ; idx < this.length ; idx++) {

         if (result) {
             result = result * this[idx];
         } else {
             result = this[idx];
         }
     }

     return result;
 };

 return ArrayLike
 })();

var al = new ArrayLike(5);

al.__proto__ = ArrayLike.prototype;

console.log(al.length, al.multiple(), al); 

これは Chrome で表示されます: 5 120 [1, 2, 3, 4, 5]

于 2016-01-11T19:12:15.797 に答える
0

これがあなたが探しているものだと思います。toString関数をオーバーライドします。

foo.prototype.toString = function()
{
    return "[object Foo <" + this[0] +">]";
}
于 2012-08-09T15:26:11.527 に答える