_.each (list, iterator, [context])의 컨텍스트는 무엇입니까?
underscore.js를 처음 사용합니다. 의 목적은 무엇인가 [context]
에가 _.each()
? 어떻게 사용해야합니까?
context 매개 변수 this
는 iterator 함수 의 값을 설정합니다 .
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/
반복되는 Array의 각 멤버의 숫자를 사용하여의 인덱스에서 항목을 가져옵니다 . 이는 컨텍스트 매개 변수로 전달한 이후 someOtherArray
로 표시됩니다 this
.
컨텍스트를 설정하지 않으면 객체를 this
참조 window
합니다.
context
this
iterator 함수 에서 참조되는 곳 입니다. 예를 들면 다음과 같습니다.
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);
제한된 예제에서도 재사용 가능한 코드를 만드는 데 "추가 인수"가 얼마나 강력한 지 알 수 있습니다. 각 상황마다 다른 콜백 기능을 만드는 대신 일반적으로 하위 수준 도우미를 조정할 수 있습니다. 목표는 최소한의 상용구로 사용자 지정 논리에 동사와 두 개의 명사를 묶는 것입니다.
분명히 화살표 함수는 일반적인 순수 함수의 많은 "코드 골프"장점을 제거했지만 의미 및 일관성 이점은 여전히 남아 있습니다.
기본 요소를 전달할 때 항상 "use strict"
기본 [].map()
호환성 을 제공하기 위해 헬퍼에 추가 합니다 . 그렇지 않으면 객체로 강제 변환되어 일반적으로 작동하지만 유형별로 빠르면 더 안전합니다.
As explained in other answers, context
is the this
context to be used inside callback passed to each
.
I'll explain this with the help of source code of relevant methods from underscore source code
The definition of _.each
or _.forEach
is as follows:
_.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;
};
Second statement is important to note here
iteratee = optimizeCb(iteratee, context);
Here, context
is passed to another method optimizeCb
and the returned function from it is then assigned to iteratee
which is called later.
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);
};
};
As can be seen from the above method definition of optimizeCb
, if context
is not passed then func
is returned as it is. If context
is passed, callback function is called as
func.call(context, other_parameters);
^^^^^^^
func
is called with call()
which is used to invoke a method by setting this
context of it. So, when this
is used inside func
, it'll refer to 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>
You can consider context
as the last optional parameter to forEach
in JavaScript.
Simple use of _.each
_.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>
Here's simple example that could use _.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();
Output:
items: [ 'banana', 'apple', 'kiwi' ]
Instead of calling addItem
multiple times you could use underscore this way:
_.each(['banana', 'apple', 'kiwi'], function(item) { x.addItem(item); });
which is identical to calling addItem
three times sequentially with these items. Basically it iterates your array and for each item calls your anonymous callback function that calls x.addItem(item)
. The anonymous callback function is similar to addItem
member function (e.g. it takes an item) and is kind of pointless. So, instead of going through anonymous function it's better that _.each
avoids this indirection and calls addItem
directly:
_.each(['banana', 'apple', 'kiwi'], x.addItem);
but this won't work, as inside basket's addItem
member function this
won't refer to your x
basket that you created. That's why you have an option to pass your basket x
to be used as [context]
:
_.each(['banana', 'apple', 'kiwi'], x.addItem, x);
Full example that uses _.each and context:
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>
In short, if callback function that you pass to _.each
in any way uses this
then you need to specify what this
should be referring to inside your callback function. It may seem like x
is redundant in my example, but x.addItem
is just a function and could be totally unrelated to x
or basket
or any other object, for example:
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>
In other words, you bind some value to this
inside your callback, or you may as well use bind directly like this:
_.each(['banana', 'apple', 'kiwi'], addItem.bind(x));
how this feature can be useful with some different underscore methods?
In general, if some underscorejs
method takes a callback function and if you want that callback be called on some member function of some object (e.g. a function that uses this
) then you may bind that function to some object or pass that object as the [context]
parameter and that's the primary intention. And at the top of underscorejs documentation, that's exactly what they state: The iteratee is bound to the context object, if one is passed
참고URL : https://stackoverflow.com/questions/4946456/what-is-context-in-eachlist-iterator-context
'programing tip' 카테고리의 다른 글
한 열에서 팬더 데이터 프레임을 정렬하는 방법 (0) | 2020.06.02 |
---|---|
node.js는 시스템 명령을 동 기적으로 실행합니다 (0) | 2020.06.02 |
차단 대기열 만들기 (0) | 2020.06.02 |
if (객체 입력) 또는 if (object.hasOwnProperty (key) (0) | 2020.06.02 |
HTML 텍스트 상자에서 키보드 캐럿 위치 설정 (0) | 2020.06.02 |