我创建了一个类似原型的数组:
function METracker() {}
METracker.prototype = Object.create(Array.prototype);
METracker.prototype.myMethod = function(aStd) {
return true;
};
现在我创建一个实例:
var aInst = new METracker('a', 'b', 'c');
现在我想克隆它,所以我这样做:
var cloneInst = aInst.slice();
然而cloneInst
方法.myMethod
不再有方法将原型保留在克隆上吗?
由于
答案 0 :(得分:1)
我创建了一个类似原型的数组:
不,你没有。
功能METracker(){} METracker.prototype = Object.create(Array.prototype); METracker.prototype.myMethod = function(aStd){ 返回true; };
METracker 构造函数什么都不做,它只会在[[Prototype]]
链上返回一个带有Array.prototype的新对象。
var aInst =新的METracker(' a',' b',' c');
只返回METracker的一个实例,它没有数据,因为构造函数对传递的参数没有做任何事情。将Array.prototype分配给继承链并不意味着调用了Array构造函数。
var cloneInst = aInst.slice();
请注意,在 aInst 上调用 slice()只会返回一个新的空数组。 aInst 没有长度属性,因此 slice 的算法无需迭代。即使 aInst 具有属性, slice 也只会遍历存在的整数值从0到aInst.length - 1
。
如果要创建一个创建类似Array的对象的构造函数,请考虑以下内容:
function ArrayLike() {
// Emulate Array constructor
this.length = arguments.length;
Array.prototype.forEach.call(arguments, function(arg, i) {
this[i] = arg;
}, this);
}
ArrayLike.prototype = Object.create(Array.prototype);
var a = new ArrayLike(1,2,3);
document.write(a.length);
document.write('<br>' + a.join());
&#13;
以上只是播放代码,还有很多工作要做。修复长度问题并不容易,我不确定是否可以完成。也许需要私人&#34; fixLength&#34;方法,但像 splice 这样的方法需要调整长度并修复索引,因此你必须编写一个模拟Array构造函数的构造函数和许多重新编制索引的方法。适当调整长度(推,弹,移位,不移位等)。
答案 1 :(得分:1)
如果您要创建自己的数组,那么诀窍是扩展数组实例,而不是数组原型:
function MyAry() {
var self = [];
[].push.apply(self, arguments);
// some dark magic
var wrap = 'concat,fill,filter,map,slice';
wrap.split(',').forEach(function(m) {
var p = self[m];
self[m] = function() {
return MyAry.apply(null, p.apply(self, arguments));
}
});
// add your stuff here
self.myMethod = function() {
document.write('values=' + this.join() + '<br>');
};
return self;
}
a = new MyAry(11,44,33,22);
a.push(55);
a[10] = 99;
a.myMethod()
b = a.sort().slice(0, 4).reverse();
b.myMethod();
&#13;
基本上,您创建一个新数组(一个普通数组,而不是您的对象),包装一些Array方法,以便它们返回您的对象而不是泛型数组,并将您的自定义方法添加到该实例。所有其他数组方法和索引操作都会继续处理您的对象,因为它只是一个数组。