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

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

本文关键字:最佳 自定义方法 添加 Array 内置 对象      更新时间:2023-09-26

我已经创建了一个节点模块,其中包含一对用于数组和字符串的自定义方法。

首先,我只是像使用常规模块一样使用它,并从require获得这样的函数:

Alt 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

这个方法现在可以这样使用:

Alt 2。

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

我认为这比Alt 1好。

我的问题是,如果有任何最佳实践或准则,当添加自定义方法,如在Alt 2内置对象,如ArrayString ?

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

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

你可以考虑一个包装器函数,它将返回一个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(例如下划线),但许多库也会采用我在这里建议的方法。参见Sugar (new Sugar.Array([1,2,3]))或Lazy (Lazy([1,2,3]))。

我认为使用Alt 2不是什么大问题,但我相信过度使用会产生问题。如果我没记错的话,他们不得不完全重做《割绳子》,因为我认为性能问题很大程度上源于原型扩展。你也可以考虑把这篇文章发到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