原型在阵列式构造上的切片上丢失

时间:2016-03-15 06:02:15

标签: javascript

我创建了一个类似原型的数组:

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不再有方法将原型保留在克隆上吗?

由于

2 个答案:

答案 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;
&#13;
&#13;

以上只是播放代码,还有很多工作要做。修复长度问题并不容易,我不确定是否可以完成。也许需要私人&#34; fixLength&#34;方法,但像 splice 这样的方法需要调整长度并修复索引,因此你必须编写一个模拟Array构造函数的构造函数和许多重新编制索引的方法。适当调整长度(推,弹,移位,不移位等)。

答案 1 :(得分:1)

如果您要创建自己的数组,那么诀窍是扩展数组实例,而不是数组原型:

&#13;
&#13;
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;
&#13;
&#13;

基本上,您创建一个新数组(一个普通数组,而不是您的对象),包装一些Array方法,以便它们返回您的对象而不是泛型数组,并将您的自定义方法添加到该实例。所有其他数组方法和索引操作都会继续处理您的对象,因为它只是一个数组。