당신이 알아야 할 것 this
this
(일명 "컨텍스트")는 각 함수 내부의 특수 키워드이며 그 값 은 함수가 언제 / 어떻게 / 어디서 정의 되었는지가 아니라 함수가 어떻게 호출 되었는지에 달려 있습니다. 다른 변수와 같은 어휘 범위의 영향을받지 않습니다 (화살표 기능 제외, 아래 참조). 여기 몇 가지 예가 있어요.
function foo() {
console.log(this);
}
// normal function call
foo(); // `this` will refer to `window`
// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`
// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`
더에 대한 자세한 내용은 this
, 상기보고가 MDN 문서를 .
올바른 참조 방법 this
사용하지 마십시오 this
실제로는 this
특히 액세스하고 싶지 않지만 참조 하는 객체 에 액세스 하십시오 . 그렇기 때문에 쉬운 해결책은 단순히 해당 객체를 참조하는 새 변수를 만드는 것입니다. 변수는 임의의 이름을 가질 수 있지만 일반적인 변수는 self
및 that
입니다.
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function() {
alert(self.data);
});
}
self
일반 변수 이므로 어휘 범위 규칙을 따르고 콜백 내에서 액세스 할 수 있습니다. 또한 this
콜백 자체 의 값에 액세스 할 수 있다는 이점이 있습니다 .
명시 적으로 this
콜백 세트 -1 부
this
값이 자동으로 설정되므로 값을 제어 할 수없는 것처럼 보일 수 있지만 실제로는 그렇지 않습니다.
모든 함수에는 .bind
[docs] 메소드가 있습니다.이 메소드 this
는 값에 바인딩 된 새 함수를 반환 합니다. 이 함수는 호출 한 것과 정확히 같은 행동이 .bind
단지에, this
당신에 의해 설정되었다. 해당 함수가 언제 어떻게 호출 되더라도 this
항상 전달 된 값을 참조합니다.
function MyConstructor(data, transport) {
this.data = data;
var boundFunction = (function() { // parenthesis are not necessary
alert(this.data); // but might improve readability
}).bind(this); // <- here we are calling `.bind()`
transport.on('data', boundFunction);
}
이 경우, 우리는 콜백의 결합되는 this
의 값 MyConstructor
의 this
.
참고 : jQuery에 대한 컨텍스트를 바인딩 할 때는 jQuery.proxy
[docs]를 대신 사용하십시오. 이를 수행하는 이유는 이벤트 콜백을 바인딩 해제 할 때 함수에 대한 참조를 저장할 필요가 없기 때문입니다. jQuery는 내부적으로 처리합니다.
ECMAScript 6 : 화살표 기능 사용
ECMAScript 6에는 화살표 함수가 도입 되어 람다 함수로 생각할 수 있습니다. 그들은 자신의 this
바인딩 이 없습니다 . 대신 this
일반 변수처럼 범위 내에서 조회됩니다. 즉,에 전화 할 필요가 없습니다 .bind
. 이것이 유일한 특수 행동은 아닙니다. 자세한 내용은 MDN 설명서를 참조하십시오.
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => alert(this.data));
}
this
콜백 세트 -2 부
콜백을 허용하는 일부 함수 / 메소드도 콜백 this
이 참조해야하는 값을 허용합니다 . 이것은 기본적으로 직접 바인딩하는 것과 동일하지만 함수 / 메소드가 대신합니다. Array#map
[문서] 는 그러한 방법입니다. 서명은 다음과 같습니다.
array.map(callback[, thisArg])
첫 번째 인수는 콜백이고 두 번째 인수는 값 this
이 참조해야합니다. 다음은 좋은 예입니다.
var arr = [1, 2, 3];
var obj = {multiplier: 42};
var new_arr = arr.map(function(v) {
return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument
참고 : 값을 전달할 수 있는지 여부 this
는 일반적으로 해당 기능 / 방법의 설명서에 나와 있습니다. 예를 들어, jQuery의 $.ajax
메소드 [docs] 는 다음과 같은 옵션을 설명합니다 context
.
이 객체는 모든 Ajax 관련 콜백의 컨텍스트가됩니다.
일반적인 문제 : 콜백 / 이벤트 핸들러로 객체 메소드 사용
이 문제의 또 다른 일반적인 표현은 객체 메소드가 콜백 / 이벤트 핸들러로 사용될 때입니다. 함수는 JavaScript에서 일류 시민이며 "메소드"라는 용어는 객체 속성의 값인 함수에 대한 구어체 용어 일뿐입니다. 그러나이 함수에는 "포함"개체에 대한 특정 링크가 없습니다.
다음 예제를 고려하십시오.
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = function() {
console.log(this.data);
};
이 함수 this.method
는 click 이벤트 핸들러로 할당 document.body
되지만를 클릭하면 undefined
이벤트 핸들러 내에서 의 인스턴스가 아닌을 this
참조 하므로 기록 된 값은 document.body
입니다 Foo
.
처음에 이미 언급했듯이, this
의미하는 것은 함수가 어떻게 정의 되는지가 아니라 함수가 어떻게 호출 되는지에 달려 있습니다.
코드가 다음과 같으면 함수에 객체에 대한 암시 적 참조가없는 것이 더 분명 할 수 있습니다.
function method() {
console.log(this.data);
}
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = method;
솔루션 은 위에서 언급 한 것과 동일합니다. 사용 가능한 경우 특정 값에 .bind
명시 적으로 바인딩 this
하는 데 사용하십시오.
document.body.onclick = this.method.bind(this);
또는 익명 함수를 콜백 / 이벤트 핸들러로 사용하여 객체의 "메소드"로 함수를 명시 적으로 호출하고 객체 ( this
)를 다른 변수에 할당합니다 .
var self = this;
document.body.onclick = function() {
self.method();
};
또는 화살표 기능을 사용하십시오.
document.body.onclick = () => this.method();