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

3

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

首先,我像使用常规模块一样使用它,并从 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)添加自定义方法时,是否有任何最佳实践或指南可遵循?


2
我认为大多数人会说,“最佳实践”是不要向内置对象添加方法。 - nnnnnn
2个回答

4

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

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

您可以考虑编写一个包装函数,它将返回一个具有额外方法的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),但是许多库也会选择类似我在此提出的方法。例如Sugarnew Sugar.Array([1,2,3]))或LazyLazy([1,2,3]))。


1
在小剂量使用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


如果您不想将该函数添加到Array.prototype中,则需要使用alt 1。修改内置对象是一种不好的做法,这就是我的问题所在! - Joakim Ericsson
哦,我的眼睛欺骗了我。 我本来以为它们都在“Array”上被扩展,这让我感到困惑,不知道为什么有人会这样做。 - Lawrence Johnson
1
第一篇文章有一些有用的信息,但是将方法添加到Array.prototype并不是扩展DOM - nnnnnn
1
人们似乎在DOM和内置对象方面面临的主要问题是相同的:潜在的冲突和浏览器兼容性。第一篇文章对这些问题有一些非常详细的解释,它们都适用于两者。 - Lawrence Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接