我创建了一个node module,其中包含一些用于数组和字符串的自定义方法。
首先,我只是像常规模块一样使用它,并从require
得到这样的函数:
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
现在可以像以下方法一样使用该方法:
require('inverted-slice');
let arr1 = [1,2,3,4];
arr1.iSlice(start, stop);
我认为哪个更好 Alt 1 。
我的问题是,在将 Alt 2 等自定义方法添加到Array
或String
等内置对象时,是否有任何最佳做法或指导原则?
答案 0 :(得分:3)
扩展内置原型总是引发争论,我认为我们可以得出结论认为不被认为是最佳实践。
另一方面,如果你可以将这些自定义方法称为对象方法而不是普通函数,那确实很好。
您可能会考虑一个包装器函数,该函数将返回一个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);
要允许链接,您可以将return
中的iSliceSpliceHelper
语句更改为:
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])
)。
答案 1 :(得分:1)
小剂量我认为使用Alt 2并不是什么大不了的事,但我相信过度使用可能会产生问题。如果我没记错的话,他们必须完全重做Cut The Rope,因为性能问题我认为很大程度上源于原型扩展。您可能还想考虑在https://codereview.stackexchange.com/
上发布此内容一对夫妇参考:
http://perfectionkills.com/whats-wrong-with-extending-the-dom/