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__以及prototypeas 对于任何数字文字)并返回一个带有as和fornew Int的“Int”对象,其中的数字可以通过,与不使用的调用相同。Empty__proto__undefinedprototype.valuenew

为什么这些非常相似的功能表现如此不同,为什么会new导致第一个?这很可能是我忽略的显而易见的事情。
仅在谷歌浏览器中测试。

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 回答