仅在模块内使用已修改的Array.prototype

时间:2016-01-18 23:57:22

标签: javascript arrays

我正在努力在更大的代码库中创建一个模块。在几个实例中,我需要能够在较大的数组中连接子数组,因此数组被展平为只有一个维度。有一些库在方法名称concatAll()下提供类似的功能。

这是功能:

Array.prototype.concatAll = function concatAll() {
    return Array.prototype.concat.apply([], this);
};

此解决方案的问题在于它会修改整个代码库的每个实例中的Array.prototype。我希望能够将此数组方法链接到其他Array方法,因此我不能只创建一个执行此操作的函数。

myArray
  .filter(...)
  .map(...)
  .concatAll();

我知道我可以delete Array.prototype.concatAll,但我们的模块加载器是这样的,我只知道模块需要何时被引导到页面,而不是当模块是“un”时“引导。因此调用delete Array.prototype.concatAll会使该方法在模块中无法使用。

有没有办法可以在模块中临时添加此方法的Array原型,而不是每个数组实例都继承该方法?

1 个答案:

答案 0 :(得分:0)

第一个想法是安排让你的增强数组原型的代码在一个单独的环境中运行,例如iframe或web worker。每个此类环境中的Array对象是独立的,更改为1将不会影响其他对象。

或者,假设您担心其他人不会覆盖您的方法,您可以按如下方式定义:

Object.defineProperty(Array.prototype, "concatAll", {
  get: function () {
    return function concatAll() {
      return Array.prototype.concat.apply([], this);
    };
  },
  set: function() {
    throw new Error("Attempt to overwrite Array#concatAll!");
  }
});

如果其他人试图通过分配重新定义它,那至少会引发错误。尝试通过另一个Object.defineProperty重新定义它也会抛出,因为该属性默认情况下不可配置。

可能是次要问题:

  

此解决方案的问题在于它在整个代码库的每个实例中修改了Array.prototype。

从技术上讲,当然没有修改任何实例。如果你的意思是每个实例都会从原型中获取新方法,那当然是真的,但你有什么特别担心的呢?