아래 내용의 약 70%는 http://www.quirksmode.org/js/this.html에서 가져온 것이며, 나머지 30%는 이에 대한 저의 이해와 느낌입니다. 도움이 필요한 분들에게 조금이나마 도움이 되기를 바랍니다. . .
먼저 이 키워드에 대한 매우 일반적인 질문을 살펴보겠습니다.
var name = 'hong'
var obj = {
name: 'ru',
getName: function(){
return function(){
return this.name;
};
}
}
alert(obj.getName()())
여기서는 별 문제가 아닙니다. , 실행 결과는 :hong입니다.
코드를 약간 변경합니다.
var name = 'hong'
var obj = {
name: 'ru',
getName: function(){
var that = this
return; function(){
return that .name;
};
}
}
alert(obj.getName()())
실행 결과는 ru
실행 결과는 :ru
이 결과에 대한 이유는 아래에서 자세히 설명합니다.
[함수 소유자]
이것을 설명하려면 먼저 이 개념을 설명해야 합니다. JavaScript에서 이는 항상 현재 실행 중인 함수의 "소유자"를 가리킵니다. 더 정확하게 말하면 이 함수를 메서드로 사용하는 개체를 가리킵니다.
이 문장을 이해하는 방법은 다음 예를 보면 됩니다.
/* -- test1 -- */
function test1 () {
this.title = 'me';
alert(window['title']); 🎜>alert (this === window); //true
}
test1()
실행 결과: me, true
위의 예에서는 this가 창 개체를 가리킵니다. 그리고 윈도우 객체의 title 속성을 'me'로 작성합니다. test1은 최상위 함수이므로 그 소유자는 윈도우 객체이거나 윈도우 객체의 메소드입니다. 이해하기 어렵지 않을 것입니다. 예를 들어 위에서 test1()을 호출할 때 window.test1()로 작성할 수도 있습니다.
다음으로 div를 생성하고 div의 onclick 속성에 대한 메서드로 test1을 할당합니다.
me! div>
div를 클릭한 결과는 다음과 같습니다. 정의되지 않음, false 동시에 'me'의 속성 값을 확인할 수 있습니다. 실제로는 id가 'o'인 HtmlObject
분명히 이것은 현재 div를 가리킵니다. 즉, test1()의 소유자가 div의 HtmlObject가 됩니다. , 또는 호출할 div의 onclick 메소드가 됩니다. 이 상황은 여전히 이해하기 쉬워야 합니다.
다음으로 코드를 변경하겠습니다. 한 곳만 변경하세요.
o.onclick = test1(); // 참고: 여기에 괄호가 추가됩니다.
위 코드의 마지막 문장을 이렇게 변경한 후, div는: me, true
첫 번째 상황과 동일해지며, 이는 창을 가리킵니다. 어떤 사람들은 차이가 없다고 궁금해하고 생각할 수도 있지만 실제로는 차이가 있습니다. 여기에는 복사 및 참조 기능 문제가 포함됩니다.
【함수 복사】
o.onclick = test1;
이런 식으로 test1() 함수는 실제로 o 객체의 onclick 속성에 복사됩니다. 따라서 test1의 소유자는 o 객체가 됩니다.
o. onclick = 테스트1()
이렇게 하면 본질적으로 클릭 이벤트의 핸들을 얻었을 때 test1() 함수를 실행하라는 의미입니다. 실행에 할당하는 것이 아니라 실행을 안내한다는 점에 유의하세요. test1()의 소유자는 변경되지 않았으며 여전히 window입니다.
[함수 참조]
위와 동일하게 HTML에 호출을 인라인으로 작성하고 호출하면 여전히 참조입니다. 메소드
div 클릭 실행 결과 여전히 이것이 창을 가리킨다는 것을 나타냅니다.
[함수 복사 예]
element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
이 메소드는 this의 포인터를 현재 호출된 객체로 변경합니다.
[함수 참조 예]
element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
메소드 함수의 소유자는 변경되지 않습니다. addEventListener 및 attachmentEvent는 실제로 함수를 복사하는 대신 doSomething에 대한 참조를 설정하므로 일관성이 없다는 점에 유의해야 합니다.
[호출 방법 사용]
방금 말했듯이
를 작성해도 test() 소유자가 할 수 있습니다
function (o) {
o.title = 'me';
}
이러한 명시적인 호출은 괜찮습니다. 또는 호출 또는 적용을 사용하여 상속 방법을 가장할 수 있습니다.
함수 테스트() {
this.title = 'me'
}
이는 개체 가장의 가장 일반적인 방법이기도 합니다.
[자유변수 문제]
이렇게 길게 쓰고 나면 원래 질문으로 돌아가자:
var name = 'hong'
var obj = {
name: 'ru',
getName: function(){
return 함수(){
return this.name;
}
}
}
alert(obj.getName()())
이렇게 해서 얻은 결과는 왜 hong일까요? 초점은
return 함수() {
return this .name;
};
위에서 작성한 함수 참조 예제를 비교하면 반환된 익명 함수의 호출 방법이 다음과 동일하다는 것을 어렵지 않게 찾을 수 있습니다. onclick = function () {doSomething()} 동일합니다. 따라서 이 메서드는 이 함수의 소유자를 변경하지 않습니다. 비록 중첩된 함수이지만 해당 선언은 최상위 수준입니다. 그 중 이것은 창을 가리킨다.
두 번째 방법은 이것을 getName()의 해당 항목에 강제로 할당하는 것입니다. 즉, that.name은 실제로 getName()의 this.name과 동일합니다. getName의 컨텍스트에서 소유자는 obj 객체이므로 이는 obj를 가리킬 것이므로 this.name === obj.name
이렇게 큰 순환을 겪었지만 잘 모르겠습니다. 나는 당신에게 그것을 분명히 했습니다.
사실 다음과 같이 요약할 수 있습니다. 이것이 위치한 함수 컨텍스트에서 이 함수가 "메서드" 형식으로 호출되지 않으면 이것은 창 객체를 가리키고, 그렇지 않으면 이 함수의 소유자를 가리킬 것입니다.