为什么不加载/强调将util方法放在数组原型上?

时间:2016-05-03 03:35:59

标签: javascript underscore.js

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

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

或者我错过了什么?

1 个答案:

答案 0 :(得分:2)

你不得不问原来的Underscore开发者,但我可以想到几个原因:

可插拔性问题

当Underscore于2009年首次发布时,第5版JavaScript规范只有只是出来并没有得到广泛实施。正是这个规范使得可以将不可枚举的属性添加到对象中;在此之前,向对象添加属性意味着它们出现在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来遍历数组,即使他们不应该没有安全措施。因此,他们决定不扩展内置原型,而不是破坏大量代码。

冲突

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

净度

将它们放在_上,可以清楚地表明您使用的是Underscore,而不是JavaScript数组的内置功能。<​​/ p>

其他类型对象的实用程序

许多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>