代码之家  ›  专栏  ›  技术社区  ›  Shamasis Bhattacharya

在JavaScript中,如何使用[]操作符访问从数组继承的对象?

  •  3
  • Shamasis Bhattacharya  · 技术社区  · 15 年前

    我遇到了一种情况,需要创建一个从数组继承的新JavaScript对象。我正在使用以下代码:

    // Create constructor function.
    var SpecialArray = function () {};
    
    // Create intermediate function to create closure upon Array's prototype.
    // This prevents littering of native Array's prototype.
    var ISpecialArray = function () {};
    ISpecialArray.prototype = Array.prototype;
    SpecialArray.prototype = new ISpecialArray();
    SpecialArray.prototype.constructor = SpecialArray;
    
    
    // Use Array's push() method to add two elements to the prototype itself.
    SpecialArray.prototype.push('pushed proto 0', 'pushed proto 1');
    
    // Use [] operator to add item to 4th position
    SpecialArray.prototype[4] = 'direct [] proto to 4';
    
    // Create new instance of Special Array
    var x = new SpecialArray();
    
    // Directly add items to this new instance.
    x.push('pushed directly on X');
    x[9] = 'direct [] to 9'
    
    console.log(x, 'length: ' + x.length);
    

    非常有趣的是,[]操作似乎毫无用处,控制台输出是:

    ["pushed proto 0", "pushed proto 1", "pushed directly on X"] length: 3
    

    我错过了什么?

    3 回复  |  直到 15 年前
        1
  •  4
  •   budinov.com    15 年前

    最好的解决方案是只扩展array类并按原样使用它。 我不喜欢另外两种选择,但它们确实存在

        2
  •  3
  •   Ollie Edwards    15 年前

    为了证明这一点,请在示例末尾添加以下内容:

    console.log(x[4]);
    

    正如您所看到的,您的条目是存在和正确的,它只是不是有序数组的一部分。

    与javascript中的其他内容一样,Array对象只是一个带有字符串键的关联数组。隐藏非数字、非序列键,让您误以为这是一个“正确的”数字索引数组。

    正如您现在已经注意到的,当迭代类似这样的结构时,不连续的键不会出现,这对于有序信息数组的一般用例是有意义的。它不太有用,或者当你想获得关键信息时,它实际上是无用的。我敢说,如果排序不重要,应该使用对象而不是数组。如果同时需要有序和无序,则将数组作为属性存储在对象中。

        3
  •  0
  •   Dustin Poissant    9 年前

    我发现创建“数组”子原型的最佳方法是 制作“Array”的子原型,而不是创建“Array-Like”原型的子原型。有许多原型四处游荡,试图模仿“数组”的属性,同时仍然能够从中“继承”,我发现最好的一个是 Collection [] . 主要的缺点是它不能很好地与非数字键(即。 myArray["foo"] = "bar"

    http://codepen.io/dustinpoissant/pen/AXbjxm?editors=0011

    var MySubArray = function(){
      Collection.apply(this, arguments);
      this.myCustomMethod = function(){
        console.log("The second item is "+this[1]);
      };
    };
    MySubArray.prototype = Object.create(Collection.prototype);
    
    var msa = new MySubArray("Hello", "World");
    msa[2] = "Third Item";
    console.log(msa);
    msa.myCustomMethod();