在我对制作类似数组对象的调查中,我做了这个函数,
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
返回数字的正常实例(__proto__
和prototype
,与任何数字文字一样),new Int
返回带有{的{Int“对象{1}}为Empty
,__proto__
为undefined
,prototype
可提供号码,与不使用.value
的号码相同。
为什么这些非常相似的函数的行为如此不同,为什么new
导致第一个?很可能是我忽略了一些明显的东西
仅在Google Chrome中测试过。
答案 0 :(得分:1)
实际上,您的Array2
函数返回真正的数组,而不仅仅是类似数组的对象,这在将[[prototype]]
设置为{0}时不会改变继承自Array.prototype
的对象(尽管您不应该使用[]
创建数组,但使用Object.create(Array.prototype)
创建一个普通对象。
您的功能Int
有几个问题。
out
是原始数字值,没有属性。在分配一些时,它将被隐式地转换为Number
对象,该对象将在之后被丢弃。 Int.prototype = 0
上的“构造函数”属性存在同样的问题。
此外,您不能使用0
之类的原始值作为原型对象。创建new Int
实例时,它将从默认Object.prototype
继承,因为0
不是“对象”类型。我不确定在将此类属性分配给非标准__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}
});