这是子类化数组的棘手解决方案吗?

时间:2013-02-20 01:43:43

标签: javascript

今天正在开发一个新的SVG框架我正在尝试将数组子类化以处理节点...几个小时后我完成了这个代码(我只通过Safari测试):

customArray=function(){
    // Do the thing
    this.__proto__= Array.prototype;

    // Add some prototypes to the main customArray
    this.f1=function(){console.log(1)}; // f1 custom function
    this.f2=function(){console.log(2)}; // f2 custom function
};

newCustomArray=new customArray();
newCustomArray.f3=function(){console.log(3)}  // f3 function only for newCustomArray

console.log(newCustomArray instanceof Array); // true
console.log([] instanceof Array);             // true
console.log("---------------------"); 
console.log(newCustomArray.f1);               // function(){console.log(1)};
console.log(newCustomArray.f2);               // function(){console.log(2)};
console.log(newCustomArray.f3);               // function(){console.log(3)};
console.log([].f1);                           // undefined
console.log([].f2);                           // undefined
console.log([].f3);                           // undefined
console.log("---------------------");
console.log(newCustomArray.forEach);          // Native function
console.log([].forEach);                      // Native function

对我而言,正如“系统”所说 proto 并非无处不在。

2 个答案:

答案 0 :(得分:3)

不,您不希望CustomArray构造函数成为Array(具有数组方法)。与此相关的是:

newCustomArray instanceof Array; // false, should be true
newCustomArray.forEach; // undefined, should be [].forEach

继续阅读How ECMAScript 5 still does not allow to subclass an array。上面的两个属性都很容易实现,但实际问题是length属性(对newCustomArray也不起作用)。

答案 1 :(得分:0)

以下是一种获得类似于子类数组的方法,我试试这个,对我来说不是最好的,但可用。

你的想法是什么?

http://jsfiddle.net/microbians/837rv/

    listOfCustomArrays   =[];
    listOfCustomArrays.fn={};
    Array_prototype=Array.prototype;

    Array=function(){

        // Add a new custom array to the list
        listOfCustomArrays.push([]); // NEW ARRAY
        listOfCustomArrays[listOfCustomArrays.length-1].index=listOfCustomArrays.length-1;

        // The the current last
        var arr=listOfCustomArrays[listOfCustomArrays.length-1];

        for (j in listOfCustomArrays.fn) {
            Object.defineProperty(arr, j, {
                value: listOfCustomArrays.fn[j]
            });
        }

        return arr
    };

    Array.extend=function(name,fnc) {
        listOfCustomArrays.fn[name]=fnc;
        for (i=0; i<listOfCustomArrays.length; i++) {
            Object.defineProperty(listOfCustomArrays[i], name, {
                value: listOfCustomArrays.fn[name]
            });
        }
    }

    Array.prototype=Array_prototype;

    newCustomArray=new Array();

    //Array.extend('f1', function(){console.log(1)} );
    Array.prototype.f1=function(){console.log('f1:prototyped')};

    Array.extend('f2', function(){console.log('f2:extended')} );
    Array.extend('f3', function(){console.log('f3:extended')} );

    newCustomArray2=new Array();
    Array.extend('f4', function(){console.log('f4:extended')} );

    console.log(typeof Array);
    console.log(typeof []);
    console.log("---------------------");
    console.log(newCustomArray.f1);
    console.log(newCustomArray.f2);
    console.log(newCustomArray.f3);
    console.log(newCustomArray.f4);
    console.log("---------------------");
    console.log(newCustomArray2.f1);
    console.log(newCustomArray2.f2);
    console.log(newCustomArray2.f3);
    console.log(newCustomArray2.f4);
    console.log("---------------------");
    console.log([].f1);
    console.log([].f2);
    console.log([].f3);
    console.log([].f4);
    console.log("---------------------");
    console.log(newCustomArray.forEach);
    console.log(newCustomArray2.forEach);
    console.log([].forEach);
    console.log(Array.prototype.forEach);