使用我的自定义方法创建对象数组的克隆



是否可能创建对象数组的克隆?我不想扩展数组对象本身,因为我的应用程序的所有数组不应暴露我的特定方法。只有一个特定的阵列。

var Arr = function () {};
Arr.prototype = Object.create( Array.prototype );
Arr.prototype.push = function() {
    // Some custom code here
    Array.prototype.push.apply( this, arguments );
};

此示例使用方法很好地工作,但是如果我从字面上设置值,则长度不会增加。因为ARR实际上是一个对象。

var arr1 = new Arr();
arr1[1] = 13;
console.log(Object.prototype.toString.call( arr1 ), arr1, arr1.length); // [object Object] { '1': 13 } 0
var arr2 = new Array();
arr2[1] = 13;
console.log(Object.prototype.toString.call( arr2 ), arr2, arr2.length); // [object Array] [ , 13 ] 2

在ES5和更早之前,您无法"子类" Array(也就是说,基于Array构造函数和Array.prototype创建自己的构造函数和原型),并为魔术属性获得正确的处理,但截至ES2015(又称" ES6"),可以以几种不同的方式,最容易的是新的class东西:

// REQUIRES ES2015+!
class MyArray extends Array {
    constructor(...args) {
        super(...args);
    }
    lengthTimesTwo() {
        return this.length * 2;
    }
    cappedJoin() {
        return this.map((s) => s.toUpperCase()).join();
    }
}
var a = new MyArray("one", "two", "three");
console.log("lengthTimesTwo: " + a.lengthTimesTwo());
console.log("cappedJoin: " + a.cappedJoin());

在ES5世界中,您可以跳过以真正接近的篮球,而人们建立像Babel这样的跨科学家(如果您遇到针对ES5环境,您可能想使用class和Transpile),但是大多数创建一个构建数组然后将方法添加到该特定实例的函数的时间足够好:

var arrayExtras = {
  lengthTimesTwo: function() {
    return this.length * 2;
  },
  cappedJoin: function() {
      return this.map(function(s) {
        return s.toUpperCase();
      }).join();
    }
    //...and so on...
};
function myArray() {
  var key, rv = [];
  rv.push.apply(rv, arguments);
  for (key in arrayExtras) {
    Object.defineProperty(rv, key, { // Add the method as a non-enumerable property
        value: arrayExtras[key],
        writable: true
    });
    // For pre-ES5 support, change the call above to simply:
    // rv[ley] = arrayExtras[key];
  }
  return rv;
}
var a = myArray("one", "two", "three");
console.log("lengthTimesTwo: " + a.lengthTimesTwo());
console.log("cappedJoin: " + a.cappedJoin());

最新更新