【问题标题】:Can I add javascript Prototype to my array instance?我可以将 javascript Prototype 添加到我的数组实例吗?
【发布时间】:2016-06-10 15:59:31
【问题描述】:

所以我知道您可以向您的 javascript 对象原型添加新方法。 myObject.prototype.myFunction = function {}。我想为我的数组实例做同样的事情,但不断出错。像这样的东西。

var myArray = [1,2,3,4,5,6,7,8,9,0]; 

myArray.prototype.bubbleSort = function(){

// sort stuff here. 

}

为什么不允许这样做?我想既然数组继承自 Object ,你应该能够像对象一样扩展它们。

如果这不可能,我该如何添加 .符号函数调用我的数组,所以我可以说。 myArray.bubbleSort(); 而不是 bubbleSort(myArray); 而不向 Array.prototype 添加方法。


我认为我的问题引起了一些混乱,所以请在回答之前阅读本节。谢谢。

我的目标是有一个名为myArray 的数组,它有一个特定的方法bubbleSort。我不想更改主要的 Array.Prototype。

所以以后我可以做这样的事情。 var yourArray = new myArray() 所以现在因为yourArray 是myArray 的实例,它将可以访问bubblesort 函数。

我们可以在不改变主 Array.prototype 的情况下实现这一点吗?

【问题讨论】:

  • 是的,数组 .prototype.bubbleSort
  • 或myArray.constructor.prototype.bubbleSort = function(){…};。
  • 如果只希望在单个实例上,直接添加即可。 myArray.bubbleSort = function() { ... };。就那么简单。将其添加到原型意味着它将被添加到许多实例中。
  • @xofux 谢谢。这行得通,但你能详细说明为什么这行得通吗?它有副作用吗?一旦我这样做,所有其他数组方法都会起作用吗?
  • @YasinYaqoobi 根据您的更新,juvian 有正确答案。

标签: javascript arrays prototype prototypal-inheritance


【解决方案1】:

数组也是对象,因此您可以轻松地将其作为函数添加到该数组中:

var myArray = [1,2,3,4,5,6,7,8,9,0]; 
myArray.bubbleSort  = function(){console.log(this)}

请注意,如果您在库中执行此操作,您可能会破坏如下代码:

for(var i in myArray){
    console.log(i)
}

因为这也会给出bubbleSort属性

一个更好的方法是扩展一个数组来做一个包装器:

function sortableArray(){
    return this
}

sortableArray.prototype = Object.create(Array.prototype);

sortableArray.prototype.bubbleSort = function(){
  console.log(this)
}

var arr = new sortableArray()
arr.push(1)
arr.push(0)
arr.push(9)
arr.bubbleSort();

【讨论】:

  • “更好的方式” 并不完全复制数组。例如,.length 属性的突变不会像您期望的那样运行。向对象添加函数实际上不会使用for-in 破坏代码。如果他们使用这种循环,那么他们应该期望获得所有可枚举的属性。如果他们只想要索引,他们会使用 for 循环。
  • @squint 你是对的,除非你有另一个库设置 array.bubbleSort 属性的风险,否则应该首选第一种方法
【解决方案2】:

我认为您误解了原型的用途。原型为对象提供了一个链,以将其他属性和方法链接到给定的对象。

例如,当你创建一个数组时

[]

该数组可以访问各种函数,如forEach、reduce 等,因为它们链接到原型或通过原型继承。修改该原型将修改从同一原型继承的所有对象。

var aNewArray = [6, 7, 8];
var myArray = [1, 2, 3, 4, 5];

// myArray.constructor.prototype will give you access to myArrays prototype
myArray.constructor.prototype.forMyArrayOnly = function() {
  console.log(this === myArray ? 'this is myArray' : 'this is NOT myArray!');
};

myArray.forMyArrayOnly();
aNewArray.forMyArrayOnly();

如果你只是想给一个单个对象添加一个方法或属性,你不想修改它们的原型链。相反,您希望将该属性直接添加到对象中。

var myArray = [1, 2, 3, 4, 5];
myArray.bubbleSort = function() {
  console.log('I totally just did bubble sort. Check it out');
  console.log(this);
};

myArray.bubbleSort();

【讨论】:

    【解决方案3】:

    你应该使用Array.prototype.bubbleSort

    var myArray = [1,2,3,4,5,6,7,8,9,0]; 
    
    Array.prototype.bubbleSort = function(){
    
        console.log("Do bubble sort here");
    
    }
    
    myArray.bubbleSort();

    【讨论】:

    • 谢谢,但我已经知道了。我的问题是关于扩展单个实例。
    • @YasinYaqoobi 他的意思不是使用myArray.prototype.bubbleSort(),正确的语法是:Array.prototype.bubbleSort()
    • :) 我理解正确的语法,但我故意这样写,以确保我不想添加到主 Array.prototype 中。我只想更改一个实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2018-07-01
    • 2019-09-07
    相关资源
    最近更新 更多