为什么不 loadash/underscore 将 util 方法放在数组原型上?

why don't loadash/underscore put the util method on array prototype?

为什么 util 方法没有将 eachmap 等函数放在数组原型上?

下划线 _ 让我的代码长了 ?不应该更整洁吗?

还是我漏掉了什么?

你得问问最初的 Underscore 开发者,但我能想到几个原因:

可枚举性问题

Underscore 于 2009 年首次发布时,第 5 版 JavaScript 规范 刚刚 出来,并没有得到广泛实施。正是该规范使得向对象添加 non-enumerable 属性成为可能;在那之前,向对象添加属性意味着它们出现在 for-in 循环中。这输出 "foo",例如:

Array.prototype.foo = function() {};
for (var k in []) {
    console.log(k);
}

示例:

Array.prototype.foo = function() {};
for (var k in []) {
    log(k);
}

function log(msg) {
    var p = document.createElement('p');
    p.appendChild(document.createTextNode(msg));
    document.body.appendChild(p);
}

从 ES5 开始,可以改为这样做:

Object.defineProperty(Array.prototype, "foo", {
    value: function() { }
});

...这使得 foo 属性 不可枚举 (不会出现在 for-in 循环等中) , 但同样,当 Underscore 出现时,那是全新的。

很多人使用 for-in 来遍历数组,尽管他们不应该没有安全措施。因此,与其破坏大量代码,他们决定不扩展内置原型。

冲突

即使没有可枚举性问题,在通用库中扩展内置原型也不一定是个好主意。 Underscore 可能想出的有用功能的任何名称都可能很容易被 TC-39 委员会在 JavaScript 的未来版本中使用,从而导致冲突。

清晰度

将它们放在 _ 上可以清楚地表明您使用的是下划线,而不是 JavaScript 数组的内置功能。

对其他类型对象的实用性

许多 Underscore 方法适用于任何 类数组,而不仅仅是数组。使这些方法在 _ 而不是 Array.prototype 上可用使得在非数组上使用它们更简单。例如,考虑 _.pluck,它可以方便地用于 DOM 元素集合(类似于数组,但不是数组):

var values = _.pluck(document.querySelectorAll("input"), "value");

示例:

var values = _.pluck(document.querySelectorAll("input"), "value");

var p = document.createElement('p');
p.appendChild(document.createTextNode(values.join(", ")));
document.body.appendChild(p);
<input type="text" value="one">
<input type="text" value="two">
<input type="text" value="three">
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>