【问题标题】:Unable to extend javascript prototype无法扩展 javascript 原型
【发布时间】:2017-01-15 05:03:30
【问题描述】:

我只是在玩弄用 Javascript 子类化的想法。我喜欢假装扩展原生对象(如数组、字符串等)是个坏主意。不管这是多么真实,我完全不明白为什么。

话虽如此,让我们继续吧。

我想做的是扩展 Array(现在,extend 可能不适合我正在做的事情)

我想创建我的新类MyArray,并且我想在上面设置 2 个方法。 .add.addMultiple

所以我是这样实现的。

function MyArray(){
    var arr = Object.create(Array.prototype);
    return Array.apply(arr, arguments);
}

MyArray.prototype = Array.prototype;

MyArray.prototype.add = function(i){
    this.push(i);
}

MyArray.prototype.addMultiple = function(a){
    if(Array.isArray(a)){
        for(var i=0;i<a.length;i++){
            this.add(a[i]);
        }
    }
}

这可以正常工作,但如果我这样做了

console.log(Array.prototype.addMultiple );
console.log(Array.prototype.add);

我得到[Function][Function]。 所以这意味着我的代码正在修改本机 Array 对象。我试图避免的事情。如何更改此代码以使这两个console.logs 将给我undefined 但我仍然能够使用本机Array.prototype 方法,例如.push

TIA

【问题讨论】:

    标签: javascript inheritance prototype extend


    【解决方案1】:
    Object.create(Array.prototype);
    

    这只是创建一个新对象并返回对象。

    因此,根据您的场景,您刚刚创建了数组对象并为您的数组对象添加了一些方法 - MyArray。会影响原生Array。

    你只是在修改你的克隆对象。

    【讨论】:

      【解决方案2】:

      使用类extension

      class MyArray extends Array {
        add(i) {
          this.push(i);
          return this;
        }
        addMultiple(a) {
          if (Array.isArray(a)) {
            for (var i = 0; i < a.length; i++) {
              this.add(a[i]);
            }
          }
          return this;
        }
      }
      
      var test = new MyArray();
      test.addMultiple([1,2,3,4,5]).add(6).add(7);
      console.log(test, test.indexOf(6));

      【讨论】:

      • 谢谢,我想用 ES5 来做!
      【解决方案3】:

      您应该设置正确的原型链:

      function MyArray(){
          Array.apply(this, arguments);
      }
      
      MyArray.prototype = Object.create(Array.prototype);
      

      Object.create 只是创建具有指定原型的新对象,所以在此操作后以下为真:

      MyArray.prototype !== Array.prototype; // true
      Object.getPrototypeOf(MyArray.prototype) === Array.prototype; // true
      

      【讨论】:

      • function MyArray(构造函数)的当前内容不是真的必要也是正确的吗?
      • 不,这样做不允许我这样做MyArray.prototype.add.add 将未定义。
      • @Katana314:不!构造函数中的var arr = Object.create(Array.prototype); 只是var arr = [] 的显式表达方式;
      • 使用Object,create(Array.prototype);给我TypeError: collection.add is not a function
      • 它还将评估console.log(collection instanceof MyArray);false
      【解决方案4】:

      这个:

      MyArray.prototype = Array.prototype;

      导致 MyArray.prototype 指向与 Array.prototype 相同的对象。所以之后你对 MyArray.prototype 所做的一切也会对 Array.prototype 进行。

      解决这个问题的一种方法是在 MyArray 中存储 Array 原型的浅表副本:

      MyArray.prototype = clone(Array.prototype);

      我从这里复制的:

      Copy prototype for inheritance?

      【讨论】:

      • 谢谢,我去看看
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      • 2013-12-02
      • 1970-01-01
      • 2016-07-29
      相关资源
      最近更新 更多