Subclassing Javascript Arrays. TypeError: Array.prototype.toString is not generic

后端 未结 7 1271
独厮守ぢ
独厮守ぢ 2020-11-28 06:30

Is it possible to subclass and inherit from javascript Arrays?

I\'d like to have my own custom Array object that has all the features of an Array, but contains addit

7条回答
  •  情歌与酒
    2020-11-28 07:04

    Checkout this. It works as it should in all browsers which support '__proto__'.

    var getPrototypeOf = Object.getPrototypeOf || function(o){
        return o.__proto__;
    };
    var setPrototypeOf = Object.setPrototypeOf || function(o, p){
        o.__proto__ = p;
        return o;
    };
    
    var CustomArray = function CustomArray() {
        var array;
        var isNew = this instanceof CustomArray;
        var proto = isNew ? getPrototypeOf(this) : CustomArray.prototype;
        switch ( arguments.length ) {
            case 0: array = []; break;
            case 1: array = isNew ? new Array(arguments[0]) : Array(arguments[0]); break;
            case 2: array = [arguments[0], arguments[1]]; break;
            case 3: array = [arguments[0], arguments[1], arguments[2]]; break;
            default: array = new (Array.bind.apply(Array, [null].concat([].slice.call(arguments))));
        }
        return setPrototypeOf(array, proto);
    };
    
    CustomArray.prototype = Object.create(Array.prototype, { constructor: { value: CustomArray } });
    CustomArray.prototype.append = function(var_args) {
        var_args = this.concat.apply([], arguments);        
        this.push.apply(this, var_args);
    
        return this;
    };
    CustomArray.prototype.prepend = function(var_args) {
        var_args = this.concat.apply([], arguments);
        this.unshift.apply(this, var_args);
    
        return this;
    };
    ["concat", "reverse", "slice", "splice", "sort", "filter", "map"].forEach(function(name) {
        var _Array_func = this[name];
        CustomArray.prototype[name] = function() {
            var result = _Array_func.apply(this, arguments);
            return setPrototypeOf(result, getPrototypeOf(this));
        }
    }, Array.prototype);
    
    var array = new CustomArray(1, 2, 3);
    console.log(array.length, array[2]);//3, 3
    array.length = 2;
    console.log(array.length, array[2]);//2, undefined
    array[9] = 'qwe';
    console.log(array.length, array[9]);//10, 'qwe'
    console.log(array+"", array instanceof Array, array instanceof CustomArray);//'1,2,,,,,,,,qwe', true, true
    
    array.append(4);
    console.log(array.join(""), array.length);//'12qwe4', 11
    

提交回复
热议问题