3

配列のようなオブジェクトを作成するための調査で、この関数を作成しました。

Array2 = function(){
    var out = [];
    Object.defineProperty(out, 'prototype', { value : Array2.prototype }); // store a reference
    out.__proto__ = Array2.prototype; // necessary as Array uses __proto__ and not prototype

    if(arguments.length > 1) Array.prototype.push.apply(out, arguments);   // re-implement constructor's
    else if(arguments.length === 1) out.length = arguments[0];             // argument handling behaviour

    return out;
};

// allow for normal prototyping behaviour
Array2.prototype = [];
Object.defineProperty(Array2.prototype, 'constructor', { value : Array2 });

Array2()そして、呼び出しが呼び出しと同じものを返すことに気づきましたnew Array2()。これは私が期待していたものではないので、整数に対して同様の関数を検討しました。

Int = function(n){
    var out = ~~n;
    out.prototype = Int.prototype;
    out.__proto__ = Int.prototype;

    this.value = out; // added to check value when working as object

    return out;
};

Int.prototype = 0;
Int.prototype.constructor = Int;

今回Intは、Numberの通常のインスタンス(__proto__およびprototype任意の数値リテラル)を返し、。を使用せずに呼び出すのと同じように、を介して使用可能な番号を使用して、asおよびfornew Intを含む「Int」オブジェクトを返します。Empty__proto__undefinedprototype.valuenew

これらの非常に類似した関数の動作が非常に異なるのはなぜnewですか。また、最初の関数が結果として得られるのはなぜですか。それはおそらく私が見落としていた明らかな何かです。
GoogleChromeでのみテストされています。

4

1 に答える 1

1

実際、Array2関数は配列のようなオブジェクトだけでなく実際の配列を返します。これは、を継承するオブジェクトに設定しても変更されません(ただし、を使用して配列を作成するべきではなく、を使用してプレーンオブジェクトを作成する必要があります。[[prototype]]Array.prototype[]Object.create(Array.prototype)

関数Intにはいくつかの問題があります。

outはプリミティブ数値であり、プロパティはありません。一部を割り当てると、オブジェクトに暗黙的にキャストされ、Number直後に破棄されます。の「コンストラクタ」プロパティに関する同じ問題Int.prototype = 0

0また、プロトタイプオブジェクトのようにプリミティブ値を使用することはできません。インスタンスを作成すると、 「オブジェクト」タイプではないため、new Intデフォルトから継承されます。非標準のプロパティにそのようなものを割り当てるとどうなるかはわかりませんが、失敗するだけだと思います。Object.prototype0__proto__

代わりにこれを使用してください:

function Int(n){
    var out = ~~n;
    this.valueOf = function(){ return out; };
    return out; // when not used as a constructor, return int-casted number
};

Int.prototype = Object.create(Number.prototype, {
    constructor:{value:Int}
});
于 2012-09-26T16:04:51.570 に答える