向数组(内置对象)添加自定义方法时的最佳实践

Best practice when adding custom method to Array (Built-in object)

我创建了一个 node module,其中包含一些用于数组和字符串的自定义方法。

首先,我只是像普通模块一样使用它,并从 require 中获取函数,如下所示:

备选方案 1。

const invSlice = require('inverted-slice');
let arr1 = [1,2,3,4];
invSlice.iSlice(arr, start, stop);

这可行,但将 iSlice 作为 Array 对象上的方法调用会更好。我通过在我的库中添加以下代码解决了这个问题:

Array.prototype.iSlice = iSliceBuiltin; // iSliceBuiltin is my function

现在可以像这样使用该方法:

备选方案 2。

require('inverted-slice');
let arr1 = [1,2,3,4];
arr1.iSlice(start, stop);

我认为比 Alt 1.

更好

问题

我的问题是,在将 Alt 2 中的自定义方法添加到内置对象(如 ArrayString

我认为小剂量使用 Alt 2 没什么大不了的,但我相信过度使用会产生问题。如果我没记错的话,由于性能问题,他们不得不完全重做 Cut The Rope,我认为这在很大程度上源于原型扩展。您可能还想考虑在 https://codereview.stackexchange.com/

上发布此内容

一些参考文献:

http://perfectionkills.com/whats-wrong-with-extending-the-dom/

https://softwareengineering.stackexchange.com/questions/104320/why-is-extending-the-dom-built-in-object-prototypes-a-bad-idea

扩展内置原型一直引发争论,我认为我们可以得出结论,它不是被认为是最佳实践。

另一方面,如果您可以将这些自定义方法作为对象方法而不是普通函数来调用,那确实很好。

您可能会考虑一个包装函数,它将 return 一个 Array 实例,该实例具有为其定义的额外方法:即,不在原型上,而是在 Array 实例本身上。

您的模块可能如下所示:

function iArray(arr) {
    return Object.assign([], arr || [], {
        iSlice: iSliceBuiltin,
        iSplice: iSpliceBuiltin
    });
}

// ... your module functions come here, but excluding the changes to the Array prototype

module.exports = {
    iArray
}

然后你会像这样使用它:

const iArray = require('inverted-slice');

let arr1 = iArray([1,2,3,4]); // enrich array with extra methods
let result = arr1.iSlice(0, 1);

要允许链接,您可以将 iSliceSpliceHelper 中的 return 语句更改为:

return iArray(newArr);

所以,现在你可以写:

let arr1 = iArray([1,2,3,4]); // enrich array with extra methods
let result = arr1.iSlice(0, 1).iSlice(1, 2);

现有库可能会实现您的替代方案 1(例如 underscore), but many also go for something like I propose here. See for instance Sugar (new Sugar.Array([1,2,3])), or Lazy (Lazy([1,2,3]))。