Что такое контекст.каждый(список, итератор, [контекст])?
Я новичок подчеркнуть.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, это именно то, что они заявляют:итератор привязан к объекту контекста, если он передается