_.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上下文在被传递给eachcallback函数的内部。

我将在下划线源代码的相关方法的源代码的帮助下解释这一点

_.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>