Что такое контекст.каждый(список, итератор, [контекст])?
Я новичок подчеркнуть.js. Какова цель [context] на _.each()? Как его следует использовать?
5 ответов:
параметр context просто устанавливает значение
thisв функции итератора.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, представленнойthisтак как мы передали его в качестве параметра контекста.если вы не указали контекст, то
thisотносятся кwindowобъект.
contextгдеthisотносится к вашей функции итератора. Например: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);
контекст позволяет предоставлять аргументы во время вызова, что позволяет легко настраивать общие встроенные вспомогательные функции.
примеры:
// 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);даже из ограниченных примеров вы можете увидеть, насколько мощным может быть "дополнительный аргумент" для создания повторно используемого кода. Вместо того чтобы создавать различные функции обратного вызова для каждой ситуации, обычно можно адаптировать низкоуровневый помощник. Цель состоит в том, чтобы ваша пользовательская логика связывала глагол и два существительных с минимальным количеством шаблонный.
По общему признанию, функции arrow устранили много преимуществ "code golf" общих чистых функций, но семантические и консистентные преимущества остаются.
Я всегда добавляю
"use strict"в помошники, чтобы обеспечить уроженца[].map()совместимость при передаче примитивов. В противном случае они принуждаются к объектам, которые обычно все еще работают, но быстрее и безопаснее быть специфичными для типа.
как объяснялось в других ответах,
context- этоthisконтекст, который будет использоваться внутри обратного вызова, переданнойeach.я объясню это с помощью исходного кода соответствующих методов из подчеркивание исходного кода
определение
_.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которое называется позже.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передается, функция обратного вызова вызывается какfunc.call(context, other_parameters); ^^^^^^^
funcСcall(), который используется для вызова метода параметрthisконтексте. Итак, когда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="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>вы можете рассмотреть
contextкак последний необязательный параметр дляforEachв JavaScript.
простое использование _.каждый
_.each(['Hello', 'World!'], function(word){ console.log(word); });<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>здесь простой пример: что можно использовать
_.each:function basket() { this.items = []; this.addItem = function(item) { this.items.push(item); }; this.show = function() { console.log('items: ', this.items); } } var x = new basket(); x.addItem('banana'); x.addItem('apple'); x.addItem('kiwi'); x.show();выход:
items: [ 'banana', 'apple', 'kiwi' ]вместо
addItemнесколько раз вы можете использовать символ подчеркивания таким образом:_.each(['banana', 'apple', 'kiwi'], function(item) { x.addItem(item); });, который идентичен вызову
addItemтри раза последовательно с этими элементами. В основном это повторяет Ваш массив и для каждого элемента вызывает вашу анонимную функцию обратного вызова, которая вызываетx.addItem(item). Функция анонимного обратного вызова аналогичнаaddItemфункция-член (например, он принимает элемент) и является своего рода бессмысленным. Итак, вместо того, чтобы проходить анонимную функцию, лучше, чтобы_.eachизбегает этой косвенности и звонкиaddItemнапрямую:_.each(['banana', 'apple', 'kiwi'], x.addItem);но это не будет работать, как внутри корзины
addItemфункции-членаthisне будет ссылаться на вашxкорзина, которую вы создали. Вот почему у вас есть возможность передать свою корзинуxдля использования в качестве[context]:_.each(['banana', 'apple', 'kiwi'], x.addItem, x);полный пример использования _.каждый и контекст:
function basket() { this.items = []; this.addItem = function(item) { this.items.push(item); }; this.show = function() { console.log('items: ', this.items); } } var x = new basket(); _.each(['banana', 'apple', 'kiwi'], x.addItem, x); x.show();<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>короче, если функция обратного вызова, которую вы передаете в
_.eachв любом случае используетthisтогда вам нужно указать, чтоthisдолжно относиться к внутренней функции обратного вызова. Может показаться, чтоxявляется избыточным в моем примере, ноx.addItem- это просто функция и может быть совершенно не связан сxилиbasketили любой другой объект, например:function basket() { this.items = []; this.show = function() { console.log('items: ', this.items); } } function addItem(item) { this.items.push(item); }; var x = new basket(); _.each(['banana', 'apple', 'kiwi'], addItem, x); x.show();<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>другими словами, вы привязываете некоторое значение к
thisвнутри обратного вызова, или вы можете также использовать связать прямо вот так:_.each(['banana', 'apple', 'kiwi'], addItem.bind(x));как эта функция может быть полезна с некоторыми различными методами подчеркивания?
в общем, если какой-нибудь
underscorejsметод принимает a функция обратного вызова и если вы хотите, чтобы этот обратный вызов был вызван для некоторой функции-члена некоторого объекта (например, функция, которая используетthis), то вы можете привязать эту функцию к какому-либо объекту или передать этот объект как[context]параметр и это основное намерение. И в верхней части документации underscorejs, это именно то, что они заявляют:итератор привязан к объекту контекста, если он передается