_.each (list, iterator, [context])의 컨텍스트는 무엇입니까?


답변:


220

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합니다.


7
그 장점은 무엇입니까? 왜 someOtherArray[num]오히려 오히려 참조하지 않는가 this[num]?
csjacobs24

3
@ csjacobs24 : 로컬 변수 범위에 액세스 할 수없는 재사용 가능한 함수 집합이있는 것이 일반적입니다. 다음은 간단한 예입니다. jsfiddle.net/a6Rx4/745

1
이 답변은 질문에 대한 답변이지만, 이것이 유용한 방법의 예를 제공하면 더 좋습니다.
temporary_user_name

50

contextthisiterator 함수 에서 참조되는 곳 입니다. 예를 들면 다음과 같습니다.

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);

7

컨텍스트를 사용하면 호출시 인수를 제공하여 사전 빌드 된 일반 헬퍼 기능을 쉽게 사용자 정의 할 수 있습니다.

몇 가지 예 :

// 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()호환성 을 제공하기 위해 헬퍼에 추가 합니다 . 그렇지 않으면 객체로 강제 변환되어 일반적으로 작동하지만 유형별로 빠르면 더 안전합니다.


5

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

사용할 수있는 간단한 예 는 다음과 같습니다 _.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);

_.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();
_.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콜백 내부에 값을 바인딩 하거나 다음과 같이 bind를 직접 사용할 수도 있습니다 .

_.each(['banana', 'apple', 'kiwi'], addItem.bind(x));

이 기능이 몇 가지 다른 밑줄 방법에 어떻게 유용합니까?

일반적으로 일부 underscorejs메소드가 콜백 함수를 사용하고 일부 객체의 일부 멤버 함수 (예 :를 사용하는 함수 this) 에서 콜백을 호출하려는 경우 해당 함수를 일부 객체에 바인딩하거나 해당 객체를 [context]매개 변수 로 전달할 수 있습니다. 주요 의도. 그리고 underscorejs 문서의 맨 위에는 정확히 다음과 같이 기술되어 있습니다 . iteratee는 컨텍스트 객체에 전달됩니다


4

다른 답변에서 설명한 바와 같이, context는 IS 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);
  };
};

AS는 상기 방법의 정의에서 볼 수있는 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>

JavaScript에서 context마지막 선택적 매개 변수로 고려할 수 있습니다 forEach.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.