【问题标题】:Best practice when adding custom method to Array (Built-in object)将自定义方法添加到 Array(内置对象)时的最佳实践
【发布时间】:2017-01-19 12:53:45
【问题描述】:

我创建了一个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 等内置对象时,是否有任何最佳实践或指南可以遵循?

【问题讨论】:

  • 我想大多数人会说“最佳实践”是向内置对象添加方法。

标签: javascript node.js javascript-objects node-modules


【解决方案1】:

我认为小剂量使用 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

【讨论】:

  • 如果您不想将函数添加到 Array.prototype,则需要 alt 1。如果修改 bultin-objects 是一种不好的做法,那是我的问题!
  • 哦,我的眼睛在欺骗我。我可以发誓他们都在Array 上被扩展,这让我很困惑为什么有人会这样做。
  • 第一篇文章有​​一些有用的信息,但是向Array.prototype 添加方法并没有扩展DOM
  • 人们对于 DOM 和内置对象的主要问题似乎是相同的:潜在的冲突和浏览器兼容性。第一篇文章对它们的含义做了一些非常详细的解释,它们确实适用于两者。
【解决方案2】:

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

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

您可能会考虑一个包装函数,它将返回一个 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),但许多库也会采用我在此处提出的建议。例如,请参阅 Sugar (new Sugar.Array([1,2,3])) 或 Lazy (Lazy([1,2,3]))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多