让我们从一些代码开始:
function myArray() { }
myArray.prototype = Object.create(Array.prototype);
myArray.prototype.constructor = myArray;
所以:
var myInstance = new myArray();
myInstance.push(1);
>> 1
myInstance.length
>> 1
myInstance instanceof myArray
>> true
myInstance instanceof Array
>> true
到目前为止,一切都是标准的。我想做的是:
var myNewInstance = myInstance.concat([2,3,4]);
>> [1, 2, 3, 4]
(with the above example it's [{0: 1, length: 1}, 2, 3, 4]
myNewInstance instanceof myArray
>> true
我不知道是否有正确的方式来执行此操作...我只能通过钝的魔法来实现。
我尝试过使用Object.prototype.valueOf
来尝试说服对象,但这种情况无处可去。
myArray.prototype.concat = function() {
// We start with a new instance of our own object, myArray
var ret = new myArray();
// utilize the in-place `splice` to keep the type as `myArray`
ret.splice.apply(
// contextualize it for our own object
ret,
Array.prototype.concat.apply(
// call it with the start and end of our empty object
[0, 0],
// with our object as an array
Array.prototype.slice.call(this).concat(
// added to the arguments, as an array
Array.prototype.slice.call(arguments)
)
)
);
// since splice returns the stuff that was removed, we
// need to have an additional line here.
return ret;
}
var myNewInstance = myInstance.concat([2,3,4]);
>> {0: 1, 1: 2, 2: 3, 3: 4, length: 4}
myNewInstance instanceof myArray
>> true
这是连贯的,但它确实是黑客 - 几乎就像我做错了。