자바 스크립트 콜백 범위
콜백 함수에서 내 개체를 참조 할 때 일반 오래된 JavaScript (프레임 워크 없음)에 문제가 있습니다.
function foo(id) {
this.dom = document.getElementById(id);
this.bar = 5;
var self = this;
this.dom.addEventListener("click", self.onclick, false);
}
foo.prototype = {
onclick : function() {
this.bar = 7;
}
};
이제 새 개체를 만들 때 (DOM이로드 된 후 span # test를 사용하여)
var x = new foo('test');
onclick 함수 내부의 'this'는 foo 객체가 아닌 span # test를 가리 킵니다.
onclick 함수 내에서 foo 객체에 대한 참조를 얻으려면 어떻게해야합니까?
(다른 답변의 주석에 숨겨진 일부 설명을 추출했습니다)
문제는 다음 줄에 있습니다.
this.dom.addEventListener("click", self.onclick, false);
여기서는 콜백으로 사용할 함수 객체를 전달합니다. 이벤트 트리거가 발생하면 함수가 호출되지만 이제는 개체와 연결되지 않습니다 (this).
이 문제는 다음과 같이 클로저에 함수 (객체 참조 포함)를 래핑하여 해결할 수 있습니다.
this.dom.addEventListener(
"click",
function(event) {self.onclick(event)},
false);
변수 자체가 할당 된 이후 이 폐쇄을 만들 때 그것이 나중에라고 할 때, 폐쇄 기능은 자기 변수의 값을 기억합니다.
이를 해결하는 또 다른 방법은 유틸리티 함수를 만드는 것입니다 (그리고 이것을 바인딩 하기 위해 변수를 사용하지 마십시오 ) :
function bind(scope, fn) {
return function () {
fn.apply(scope, arguments);
};
}
업데이트 된 코드는 다음과 같습니다.
this.dom.addEventListener("click", bind(this, this.onclick), false);
Function.prototype.bind
ECMAScript 5의 일부이며 동일한 기능을 제공합니다. 따라서 다음을 수행 할 수 있습니다.
this.dom.addEventListener("click", this.onclick.bind(this), false);
아직 ES5를 지원하지 않는 브라우저의 경우 MDN은 다음 shim을 제공합니다 .
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
this.dom.addEventListener("click", function(event) {
self.onclick(event)
}, false);
를 들어 jQuery를에 이 문제에 대한 해결책을 찾는 사용자, 당신은 사용해야합니다 jQuery.proxy을
The explanation is that self.onclick
does not mean what you think it means in JavaScript. It actually means the onclick
function in the prototype of the object self
(without in any way referencing self
itself).
JavaScript only has functions and no delegates like C#, so it is not possible to pass a method AND the object it should be applied to as a callback.
The only way to call a method in a callback is to call it yourself inside a callback function. Because JavaScript functions are closures, they are able to access the variables declared in the scope they were created in.
var obj = ...;
function callback(){ return obj.method() };
something.bind(callback);
A good explanation of the problem (I had problems understanding solutions described so far) is available here.
I wrote this plugin...
i think it will be useful
this is one of the most confusing points of JS: the 'this' variable means to the most local object... but functions are also objects, so 'this' points there. There are other subtle points, but i don't remember them all.
I usually avoid using 'this', just define a local 'me' variable and use that instead.
참고URL : https://stackoverflow.com/questions/183214/javascript-callback-scope
'programing tip' 카테고리의 다른 글
CSS 이미지 최대 너비를 원본 이미지 크기로 설정 하시겠습니까? (0) | 2020.12.12 |
---|---|
Kotlin에서 Mockito를 사용할 수 있습니까? (0) | 2020.12.12 |
std :: vector.clear ()는 각 요소에서 (사용 가능한 메모리)를 삭제합니까? (0) | 2020.12.12 |
ASP.NET MVC로 로그온 시스템을 만들 수 있지만 MembershipProvider를 사용하지 않을 수 있습니까? (0) | 2020.12.12 |
정규식 일치 수 (0) | 2020.12.12 |