Ways to extend Array object in javascript

前端 未结 8 2179
[愿得一人]
[愿得一人] 2020-12-13 13:02

i try to extend Array object in javascript with some user friendly methods like Array.Add() instead Array.push() etc...

i implement 3 ways to do this. unfortunetly t

相关标签:
8条回答
  • 2020-12-13 13:13

    You can also use this way in ES6:

    Object.assign(Array.prototype, {
        unique() {
          return this.filter((value, index, array) => {
            return array.indexOf(value) === index;
          });
        }
    });
    

    Result:

    let x = [0,1,2,3,2,3];
    let y = x.unique();
    console.log(y); // => [0,1,2,3]
    
    0 讨论(0)
  • 2020-12-13 13:14

    Are you trying to do something more complicated then just add an alias for "push" called "Add"?

    If not, it would probably be best to avoid doing this. The reason I suggest this is a bad idea is that because Array is a builtin javascript type, modifying it will cause all scripts Array type to have your new "Add" method. The potential for name clashes with another third party are high and could cause the third party script to lose its method in favour of your one.

    My general rule is to make a helper function to work on the Array's if it doesnt exist somewhere already and only extend Array if its extremely necessary.

    0 讨论(0)
  • 2020-12-13 13:21

    Method names should be lowercase. Prototype should not be modified in the constructor.

    function Array3() { };
    Array3.prototype = new Array;
    Array3.prototype.add = Array3.prototype.push
    

    in CoffeeScript

    class Array3 extends Array
       add: (item)->
         @push(item) 
    

    If you don't like that syntax, and you HAVE to extend it from within the constructor, Your only option is:

    // 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)
          }
    
       });
    };
    

    You could also do this

    ArrayExtenstions = {
       Add: function() {
    
       }
    }
    extend(ArrayExtenstions, Array.prototype);
    
    
    
    function Array3() { }
    Array3.prototype = ArrayExtenstions;
    

    In olden days, 'prototype.js' used to have a Class.create method. You could wrap all this is a method like that

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

    For more info on this and how to implement, look in the prototype.js source code

    0 讨论(0)
  • 2020-12-13 13:21

    ES6

    class SubArray extends Array {
        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
    

    Using __proto__

    (old answer, not recommended, may cause performance issues)

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

    Now you can add your methods to SubArray

    SubArray.prototype.last = function() {
      return this[this.length - 1];
    };
    

    Initialize like normal Arrays

    var sub = new SubArray(1, 2, 3);
    

    Behaves like normal Arrays

    sub instanceof SubArray; // true
    sub instanceof Array; // true
    
    0 讨论(0)
  • 2020-12-13 13:25

    A while ago I read the book Javascript Ninja written by John Resig, the creator of jQuery. He proposed a way to mimic array-like methods with a plain JS object. Basically, only length is required.

    var obj = {
        length: 0, //only length is required to mimic an Array
        add: function(elem){
            Array.prototype.push.call(this, elem);
        },
        filter: function(callback) {
            return Array.prototype.filter.call(this, callback); //or provide your own implemetation
        }
    };
    
    obj.add('a');
    obj.add('b');
    console.log(obj.length); //2
    console.log(obj[0], obj[1]); //'a', 'b'
    

    I don't mean it's good or bad. It's an original way of doing Array operations. The benefit is that you do not extend the Array prototype. Keep in mind that obj is a plain object, it's not an Array. Therefore obj instanceof Array will return false. Think obj as a façade.

    If that code is of interest to you, read the excerpt Listing 4.10 Simulating array-like methods.

    0 讨论(0)
  • 2020-12-13 13:26

    You CANNOT extend the Array Object in JavaScript.

    Instead, what you can do is define an object that will contain a list of functions that perform on the Array, and inject these functions into that Array instance and return this new Array instance. What you shouldn't do is changing the Array.prototype to include your custom functions upon the list.

    Example:

    function MyArray() {
      var tmp_array = Object.create(Array.prototype);
      tmp_array = (Array.apply(tmp_array, arguments) || tmp_array);
      //Now extend tmp_array
      for( var meth in MyArray.prototype )
        if(MyArray.prototype.hasOwnProperty(meth))
          tmp_array[meth] = MyArray.prototype[meth];
      return (tmp_array);
    }
    //Now define the prototype chain.
    MyArray.prototype = {
      customFunction: function() { return "blah blah"; },
      customMetaData: "Blah Blah",
    }
    

    Just a sample code, you can modify it and use however you want. But the underlying concept I recommend you to follow remains the same.

    0 讨论(0)
提交回复
热议问题