在javascript中扩展Array对象的方法

dem*_*nes 38 javascript arrays class extend

我尝试使用一些用户友好的方法(如Array.Add()而不是Array.push()等在javascript中扩展Array对象...

我实现了3种方法.不幸的是,第三种方式不起作用,我想问为什么?以及如何做到这一点.

//------------- 1st way
Array.prototype.Add=function(element){
     this.push(element);
};

var list1 = new Array();
list1.Add("Hello world");
alert(list1[0]);

//------------- 2nd way
function Array2 () {
    //some other properties and methods
};

Array2.prototype = new Array;
Array2.prototype.Add = function(element){
  this.push(element);  
};

var list2 = new Array2;
list2.Add(123);
alert(list2[0]);

//------------- 3rd way
function Array3 () {
    this.prototype = new Array;
    this.Add = function(element){
      this.push(element);  
    };
};

var list3 = new Array3;
list3.Add(456);  //push is not a function
alert(list3[0]); // undefined
Run Code Online (Sandbox Code Playgroud)

在第三种方式,我想在内部Array3类扩展Array对象.如何做到这一点,以免"推不是一个功能"和"未定义"?

在这里,我添加第四种方式.

//------------- 4th way
function Array4 () {
    //some other properties and methods
    this.Add = function(element){
        this.push(element);
    };
 };
Array4.prototype = new Array();

var list4 = new Array4();
list4.Add(789);
alert(list4[0]);
Run Code Online (Sandbox Code Playgroud)

在这里,我必须使用原型.我希望避免在类构造函数之外使用额外的行作为Array4.prototype.我希望有一个紧凑的定义类,所有部分都放在一个地方.但我想我不能这样做.

SMa*_*hew 28

方法名称应为小写.不应在构造函数中修改原型.

function Array3() { };
Array3.prototype = new Array;
Array3.prototype.add = Array3.prototype.push
Run Code Online (Sandbox Code Playgroud)

在CoffeeScript中

class Array3 extends Array
   add: (item)->
     @push(item) 
Run Code Online (Sandbox Code Playgroud)

如果你不喜欢这种语法,并且你必须在构造函数中扩展它,你唯一的选择是:

// define this once somewhere
// you can also change this to accept multiple arguments 
function extend(x, y){
    for(var key in y) {
        if (y.hasOwnProperty(key)) {
            x[key] = y[key];
        }
    }
    return x;
}


function Array3() { 
   extend(this, Array.prototype);
   extend(this, {
      Add: function(item) {
        return this.push(item)
      }

   });
};
Run Code Online (Sandbox Code Playgroud)

你也可以这样做

ArrayExtenstions = {
   Add: function() {

   }
}
extend(ArrayExtenstions, Array.prototype);



function Array3() { }
Array3.prototype = ArrayExtenstions;
Run Code Online (Sandbox Code Playgroud)

在过去,'prototype.js'曾经有一个Class.create方法.你可以包装所有这是一个像这样的方法

var Array3 = Class.create(Array, {
    construct: function() {

    },    
    Add: function() {

    }
});
Run Code Online (Sandbox Code Playgroud)

有关此内容以及如何实现的更多信息,请查看prototype.js源代码


lag*_*lex 19

ES6

class SubArray extends Array {
    constructor(...args) { 
        super(...args); 
    }
    last() {
        return this[this.length - 1];
    }
}
var sub = new SubArray(1, 2, 3);
sub // [1, 2, 3]
sub instanceof SubArray; // true
sub instanceof Array; // true
Run Code Online (Sandbox Code Playgroud)

运用 __proto__

(旧答案,不推荐,可能会导致性能问题)

function SubArray() {
  var arr = [ ];
  arr.push.apply(arr, arguments);
  arr.__proto__ = SubArray.prototype;
  return arr;
}
SubArray.prototype = new Array;
Run Code Online (Sandbox Code Playgroud)

现在您可以添加方法了 SubArray

SubArray.prototype.last = function() {
  return this[this.length - 1];
};
Run Code Online (Sandbox Code Playgroud)

像普通数组一样初始化

var sub = new SubArray(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

像普通阵列一样

sub instanceof SubArray; // true
sub instanceof Array; // true
Run Code Online (Sandbox Code Playgroud)

  • 您应该将 `constructor` 中的值传递给 `super`,如下所示:`constructor(...items) {super(...items) }` (2认同)