ECMA 5에 대한 참조는 명확히해야합니다.
ECMA-262 Edition 5를 의미한다고 가정합니다. ECMA-262 (일명 ECMAScript 또는 덜 정확하게는 Javascript)는 인터넷 브라우저에서 구현 된 일반적인 스크립팅 언어입니다 . Edition 5.1 표준에서 :
다음 단계는 제어가 함수 객체 F에 포함 된 함수 코드, thisArg를 제공 한 호출자 및 argumentsList를 제공 한 호출자에 대한 실행 컨텍스트에 들어갈 때 수행됩니다.
- 함수 코드가 엄격한 코드 인 경우 ThisBinding을 thisArg로 설정합니다.
- 그렇지 않으면 thisArg가 null이거나 정의되지 않은 경우 ThisBinding을 전역 개체로 설정합니다.
- 그렇지 않으면 Type (thisArg)가 Object가 아닌 경우 ThisBinding을 ToObject (thisArg)로 설정합니다.
- 그렇지 않으면 ThisBinding을 thisArg로 설정합니다.
- ... ( "this"가 아님)
"전역 개체"라는 용어는 범위 체인의 맨 위에있는 개체를 가리 킵니다. 브라우저의 경우 이것은 "창"개체이지만 구현 선택 사항입니다 (Windows 스크립트 호스트에는 보이지 않는 전역 개체가 있지만 엄격 모드가 없으므로 한정되지 않은 참조가 해당 속성에 액세스하고 전역 "자체"가 없습니다). 또한 "엄격 모드"를 명시 적으로 활성화해야합니다. 그렇지 않으면 활성화되지 않습니다 (표준의 섹션 14.1). 따라서 정의되지 않은 "this"는 엄격 모드가 활성화되지 않은 "ECMA 5"의 전역 개체 (창)로 확인됩니다.
따라서 질문에 대한 답은 다음과 같습니다.
"this"는 항상 함수를 호출하는 객체를 나타냅니다. 함수가 객체에 의해 호출되지 않은 경우 (즉, 메서드 호출이 아님) "this"(함수에 전달됨)는 "정의되지 않음"입니다. 그러나 엄격 모드를 사용하지 않는 경우 정의되지 않은 "this"가 전역 객체로 설정됩니다 (위의 규칙 2).
"self"는 특별한 구문 의미가 없으며 단지 식별자 일뿐입니다. 브라우저는 window.self (전역 창 개체의 속성) = window를 정의하는 경향이 있습니다. 이로 인해 "self"가 둘러싸는 범위 내에서 재정의되지 않는 한 "self"에 대한 정규화되지 않은 참조가 "window"와 동일하게됩니다 (예 : 위의 "var self = this;"에 의해 재정의 됨. 행운을 빌어 "this"를 재정의 함).
따라서 위의 예에 대한 전체 설명은 다음과 같습니다.
outer func: this.foo = bar
// "this" refers to the invoking object "myObject"
outer func: self.foo = bar
// "self" resolves to the variable in the local scope which has been set to "this" so it is also "myObject"
inner func: this.foo = undefined
// "this" refers to the invoking object (none) and so is replaced by the global object (strict mode must be off). "window" has no foo property so its "value" is undefined.
inner func: self.foo = bar
// self resolves to the variable in the enclosing scope which is still "myObject"
예제의 흥미로운 변형은 내부 함수에 대한 참조를 반환하여 클로저를 만듭니다.
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
return function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
};
}
};
var yourObject = {
foo: "blat",
func: myObject.func() // function call not function object
};
console.log("----");
yourObject.func();
생산
outer func: this.foo = bar
outer func: self.foo = bar
----
inner func: this.foo = blat
inner func: self.foo = bar
yourObject가 호출 할 때까지 내부 함수가 어떻게 호출되지 않는지 확인하십시오. 따라서 this.foo는 이제 yourObject.foo이지만 self는 여전히 내부 함수 객체가 반환되었을 때 (그리고 결과 클로저에서는 여전히 myObject 인) 둘러싸는 범위의 변수로 확인됩니다. 따라서 내부 함수 내에서 "this"는 내부 함수를 호출하는 객체를, "self"는 내부 함수에 대한 참조를 생성하기 위해 외부 함수를 호출 한 객체를 나타냅니다.
요약 요약을 요약하면 "this"는 언어 표준에 의해 정의되고 "self"는 정의하는 사람 (런타임 구현 자 또는 최종 프로그래머)에 의해 정의됩니다.