_.each(list,iterator,)中的上下文是什么?
我是underscore.js的新手。 _.each()
的[context]
的目的是什么? 应该如何使用?
上下文参数只是在迭代器函数中设置了这个值。
var someOtherArray = ["name","patrick","d","w"]; _.each([1, 2, 3], function(num) { // In here, "this" refers to the same Array as "someOtherArray" alert( this[num] ); // num is the value from the array being iterated // so this[num] gets the item at the "num" index of // someOtherArray. }, someOtherArray);
工作示例: http : //jsfiddle.net/a6Rx4/
它使用迭代数组的每个成员的数字来获取someOtherArray
索引处的项目,由此我们将其作为上下文parameter passing给它。
如果你不设置上下文,那么this
将引用window
对象。
context
是在你的迭代器函数中引用的地方。 例如:
var person = {}; person.friends = { name1: true, name2: false, name3: true, name4: true }; _.each(['name4', 'name2'], function(name){ // this refers to the friends property of the person object alert(this[name]); }, person.friends);
正如其他答案中所解释的, context
就是this
上下文在被传递给each
callback函数的内部。
我将在下划线源代码的相关方法的源代码的帮助下解释这一点
_.each
或_.forEach
的定义如下:
_.each = _.forEach = function(obj, iteratee, context) { iteratee = optimizeCb(iteratee, context); var i, length; if (isArrayLike(obj)) { for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); } } return obj; };
第二个陈述在这里需要注意
iteratee = optimizeCb(iteratee, context);
在这里, context
被传递给另一个方法optimizeCb
然后将返回的函数分配给iteratee
调用的iteratee
。
var optimizeCb = function(func, context, argCount) { if (context === void 0) return func; switch (argCount == null ? 3 : argCount) { case 1: return function(value) { return func.call(context, value); }; case 2: return function(value, other) { return func.call(context, value, other); }; case 3: return function(value, index, collection) { return func.call(context, value, index, collection); }; case 4: return function(accumulator, value, index, collection) { return func.call(context, accumulator, value, index, collection); }; } return function() { return func.apply(context, arguments); }; };
从上面的optimizeCb
方法定义可以看出,如果context
没有通过,那么func
就会按照原样返回。 如果context
被传递,callback函数被称为
func.call(context, other_parameters); ^^^^^^^
用call()
func
,通过设置this
上下文来调用一个方法。 所以,当在func
里面使用它时,它会引用context
。
// Without `context` _.each([1], function() { console.log(this instanceof Window); }); // With `context` as `arr` var arr = [1, 2, 3]; _.each([1], function() { console.log(this); }, arr);
<script src="ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
上下文允许您在调用时提供参数,从而可以轻松定制通用预构build的帮助器函数。
一些例子:
// stock footage: function addTo(x){ "use strict"; return x + this; } function pluck(x){ "use strict"; return x[this]; } function lt(x){ "use strict"; return x < this; } // production: var r = [1,2,3,4,5,6,7,8,9]; var words = "a man a plan a canal panama".split(" "); // filtering numbers: _.filter(r, lt, 5); // elements less than 5 _.filter(r, lt, 3); // elements less than 3 // add 100 to the elements: _.map(r, addTo, 100); // encode eggy peggy: _.map(words, addTo, "egg").join(" "); // get length of words: _.map(words, pluck, "length"); // find words starting with "e" or sooner: _.filter(words, lt, "e"); // find all words with 3 or more chars: _.filter(words, pluck, 2);
即使从有限的例子中,你可以看到创build可重用代码的“额外参数”是多么强大。 对于每种情况,不要使用不同的callback函数,通常可以调整一个低级帮手。 目标是让您的自定义逻辑捆绑动词和两个名词,最小的样板。
不可否认的是,箭头函数已经消除了许多通用纯函数的“代码高尔夫球”优点,但语义和一致性优势依然存在。
我总是添加"use strict"
来帮助提供native [].map()
兼容性时传递原语。 否则,它们被强制转换成通常仍然有效的对象,但是它更快更安全。
简单使用_.each
_.each(['Hello', 'World!'], function(word){ console.log(word); });
<script src="ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>