向数组(内置对象)添加自定义方法时的最佳实践
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 中的自定义方法添加到内置对象(如 Array
或 String
?
我认为小剂量使用 Alt 2 没什么大不了的,但我相信过度使用会产生问题。如果我没记错的话,由于性能问题,他们不得不完全重做 Cut The Rope,我认为这在很大程度上源于原型扩展。您可能还想考虑在 https://codereview.stackexchange.com/
上发布此内容
一些参考文献:
http://perfectionkills.com/whats-wrong-with-extending-the-dom/
扩展内置原型一直引发争论,我认为我们可以得出结论,它不是被认为是最佳实践。
另一方面,如果您可以将这些自定义方法作为对象方法而不是普通函数来调用,那确实很好。
您可能会考虑一个包装函数,它将 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])
)。
我创建了一个 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 中的自定义方法添加到内置对象(如 Array
或 String
?
我认为小剂量使用 Alt 2 没什么大不了的,但我相信过度使用会产生问题。如果我没记错的话,由于性能问题,他们不得不完全重做 Cut The Rope,我认为这在很大程度上源于原型扩展。您可能还想考虑在 https://codereview.stackexchange.com/
上发布此内容一些参考文献:
http://perfectionkills.com/whats-wrong-with-extending-the-dom/
扩展内置原型一直引发争论,我认为我们可以得出结论,它不是被认为是最佳实践。
另一方面,如果您可以将这些自定义方法作为对象方法而不是普通函数来调用,那确实很好。
您可能会考虑一个包装函数,它将 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])
)。