[javascript] 올바른 “this”컨텍스트를 setTimeout 콜백에 전달 하시겠습니까?

컨텍스트를 setTimeout어떻게 전달 합니까? 내가 전화 할 this.tip.destroy()경우 this.options.destroyOnHide이후 1000 밀리. 어떻게해야합니까?

if (this.options.destroyOnHide) {
     setTimeout(function() { this.tip.destroy() }, 1000);
} 

위를 시도 this하면 창을 참조하십시오.



답변

편집 : 요약하면,이 질문이 제기 된 2010 년 에이 문제를 해결하는 가장 일반적인 방법 은 전역 객체 를 가리키는 함수를 실행 setTimeout하기 때문에 함수 호출이 수행 되는 컨텍스트에 대한 참조를 저장하는 것이 었습니다 .setTimeoutthis

var that = this;
if (this.options.destroyOnHide) {
     setTimeout(function(){ that.tip.destroy() }, 1000);
} 

그 전에 1 년 전에 릴리스 된 ES5 사양에서는이 bind방법을 도입했습니다.이 방법 은 아직 널리 지원되지 않았고 사용하기 위해 폴리 필이 필요했지만 지금은 어디에나 있기 때문에 원래 답변에서 제안되지 않았습니다.

if (this.options.destroyOnHide) {
     setTimeout(function(){ this.tip.destroy() }.bind(this), 1000);
}

bind함수는 this값이 미리 채워진 새 함수를 만듭니다 .

이제 현대 JS에서 이것은 화살표 기능이 ES6 에서 해결하는 문제입니다 .

if (this.options.destroyOnHide) {
     setTimeout(() => { this.tip.destroy() }, 1000);
}

화살표 함수는 this자체 값을 갖지 않으며 , 액세스 할 때 포함 this어휘 범위 의 값에 액세스합니다 .

HTML5는 2011 년에 타이머를 다시 표준화 했으며 이제 콜백 함수에 인수를 전달할 수 있습니다.

if (this.options.destroyOnHide) {
     setTimeout(function(that){ that.tip.destroy() }, 1000, this);
}

또한보십시오:


답변

@CMS가 응답 한 함수 래퍼에 대한 바로 가기 (구문 설탕)가 있습니다. (아래에서 원하는 컨텍스트가 있다고 가정하십시오 this.tip.)


ECMAScript 5 ( 현재 브라우저 , Node.js) 및 Prototype.js

ECMA-262, 5 판 (ECMAScript 5) 또는 Node.js 와 호환되는 브라우저 를 대상으로하는 경우을 사용할 수 있습니다 Function.prototype.bind. 선택적으로 함수 인수를 전달하여 부분 함수 를 작성할 수 있습니다 .

fun.bind(thisArg[, arg1[, arg2[, ...]]])

다시, 귀하의 경우, 이것을 시도하십시오 :

if (this.options.destroyOnHide) {
    setTimeout(this.tip.destroy.bind(this.tip), 1000);
}

프로토 타입 (다른 라이브러리) 에서도 동일한 기능이 구현 되었습니다 .

Function.prototype.bind사용자 정의 이전 버전과의 호환성을 원할 경우 이와 같이 구현할 수 있습니다 (하지만 참고 사항을 준수하십시오)


ECMAScript 2015 ( 일부 브라우저 , Node.js 5.0.0+)

최첨단 개발 (2015)의 경우에는 사용 지방 화살표 함수 이며, ECMA 스크립트 2,015 (조화 / ES6 / ES2015) 사양의 일부 ( ).

화살표 함수식 (라고도 지방 화살표 함수 ) 함수식에 비해 짧은 구문 및 어휘 바인드 this값 […]가.

(param1, param2, ...rest) => { statements }

귀하의 경우 다음을 시도하십시오.

if (this.options.destroyOnHide) {
    setTimeout(() => { this.tip.destroy(); }, 1000);
}

jQuery

이미 jQuery 1.4 이상을 사용하고 있다면, 함수의 this컨텍스트 를 명시 적으로 설정하기위한 기성 함수 가 있습니다.

jQuery.proxy () : 함수를 가져 와서 항상 특정 컨텍스트를 갖는 새로운 함수를 반환합니다.

$.proxy(function, context[, additionalArguments])

귀하의 경우 다음을 시도하십시오.

if (this.options.destroyOnHide) {
    setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}

Underscore.js , lodash

Underscore.js와 lodash뿐만 아니라 1 , 2 에서 사용할 수 있습니다_.bind(...)

bind 함수를 객체에 바인딩 합니다. 즉, 함수가 호출 될 때마다 값이this객체가됩니다. 선택적으로 인수를 함수에 바인드하여 부분 애플리케이션이라고도합니다.

_.bind(function, object, [*arguments])

귀하의 경우 다음을 시도하십시오.

if (this.options.destroyOnHide) {
    setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}


답변

Internet Explorer 이외의 브라우저에서는 지연 후 매개 변수를 함수에 함께 전달할 수 있습니다.

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

그래서 당신은 이것을 할 수 있습니다 :

var timeoutID = window.setTimeout(function (self) {
  console.log(self);
}, 500, this);

이것은 (캐시 룩업 범위보다 성능면에서 더 this제한 시간 / 간격 식의 변수의 외부로) 후 (사용하여 고정을 생성 $.proxy하거나 Function.prototype.bind).

Webreflection의 IE에서 작동하도록하는 코드 :

/*@cc_on
(function (modifierFn) {
  // you have to invoke it as `window`'s property so, `window.setTimeout`
  window.setTimeout = modifierFn(window.setTimeout);
  window.setInterval = modifierFn(window.setInterval);
})(function (originalTimerFn) {
    return function (callback, timeout){
      var args = [].slice.call(arguments, 2);
      return originalTimerFn(function () {
        callback.apply(this, args)
      }, timeout);
    }
});
@*/


답변

참고 : 이것은 IE에서 작동하지 않습니다

var ob = {
    p: "ob.p"
}

var p = "window.p";

setTimeout(function(){
    console.log(this.p); // will print "window.p"
},1000);

setTimeout(function(){
    console.log(this.p); // will print "ob.p"
}.bind(ob),1000);


답변

을 사용하는 경우을 사용할 underscore수 있습니다 bind.

예 :

if (this.options.destroyOnHide) {
     setTimeout(_.bind(this.tip.destroy, this), 1000);
}


답변