-
this 값은 Execution Context 의 속성 중 하나이다.
var ECStack = [ globalExecutionContext: { VO: { }, this: global object } ];
-
this 값은 해당 Execution Context 진입 시 초기화된 후, 그 값이 변하지 않는다.
// global Execution Context // 실행 코드 처리 시 새로운 값을 할당할 수 없다. this.window = null; // 실행 코드 처리 후 값이 변하지 않는다. console.log(this.window); // global object
-
레퍼런스 타입(Reference Type)
-
레퍼런스 타입은 base 와 propertyName 속성을 가진 객체로 표현할 수 있으며, 설명을 목적으로 “ECMA 스펙” 에서 정의하고 있는 개념이다.
// 아래는 레퍼런스 타입을 나타내는 pseudo-code 이다. var valueOfReferenceType = { base: <base object>, propertyName: <property name> };
-
레퍼런스 타입은 오직 두 가지 경우에만 있을 수 있다.
-
-
식별자는 변수 이름, 함수 이름, 함수 Argument 이름으로 나뉜다.
-
변수 이름
// global Execution Context // A 변수 선언 var A = 1; console.log(A); // 1
-
레퍼런스 타입 내부
var AReference = { base: global object, propertyName: 'A' };
-
함수 이름
// global Execution Context // A 함수 선언 function A(){ }; console.log(A); // A function object
-
레퍼런스 타입 내부
```javascript var AReference = { base: global object, propertyName: 'A' }; ```
-
GetValue 메서드
-
객체(레퍼런스 타입)의 실제 값을 얻기 위해 사용되는 GetValue 메소드가 존재하며, 이 메서드는 프로토타입 체인을 통해, 상속된 속성까지 모두 분석 후, 객체 속성(propertyName)의 실제 값을 반환해준다.
// GetValue 메서드를 나타내는 pseudo-code 이다. function GetValue(value) { if (Type(value) != Reference) { // 레퍼런스 타입이 아니면 값을 그대로 돌려준다. return value; } // base 속성 값을 가져온다. var base = GetBase(value); // base 속성 값이 null 인 경우 if (base === null) { throw new ReferenceError; } // propertyName 속성 값을 가져온다. var propertyName = GetPropertyName(value); // [[Get]] 메서드는 프로토타입 체인으로부터, 상속된 속성까지 모두 분석 후 속성의 실제 값을 돌려준다. return base.[[Get]](propertyName); } GetValue(ReferenceType);
-
-
-
프로퍼티 접근자(property accessor)
-
obj 객체의 A 메서드
// global Execution Context var obj = { A: function(){ return this; } }; console.log(obj.A()); // obj Object console.log(obj['A']()); // obj Object
-
레퍼런스 타입 내부
var objAReference = { base: obj Object, propertyName: 'A' };
-
GetValue 메서드를 통해 해당 속성(propertyName) 값을 반환한다.
GetValue(objAReference); // A function object
-
-
-
-
-
전역 코드 안의 this 값
-
전역 코드안의 this 는 전역 객체 자신이된다.
// global code in global Execution Context console.log(this); // global object console.log(this.window); // global object console.log(this === this.window); // true
-
-
함수 코드 안의 this 값
-
함수 코드의 경우 this 가 가리키는 대상이 매번 달라질 수 있다.
-
Function Execution Context 진입 시 this 가 가지는 초기화 값은 호출 표현식 형태에 의해 달라진다.
-
함수 코드 안의 this 값이 초기화되는 과정
-
만약 ()(함수 호출 괄호) 왼편의 (식별자 또는 프로퍼티 접근자)가 레퍼런스 타입일경우, 함수 코드 안의 this 값은 해당 레퍼런스 타입의 base 속성 값으로 초기화된다.
-
그러나 레퍼런스 타입이 아닌 경우, this 값은 자동으로 null 을 갖게되며, null 은 this 값으로 평가될 수 없기때문에, 암묵적으로 전역 객체로 변환된다.
-
A 함수
// global Execution Context function A(){ // function Execution Context // this 값은 해당 레퍼런스 타입의 base 속성 값으로 초기화된다. console.log(this); // global object }; // [호출자].[propertyName](호출괄호) this.A(); // this.A();
-
레퍼런스 타입 체크
// reference Type var AReference = { base: global object, propertyName: 'A' }; // referenceType 값을 반환한다. GetValue(AReference); // A function object
-
obj 객체의 X 메서드
// global Execution Context var obj = { X: function(){ return this; } }; console.log(obj.X()); // obj Object console.log(obj['X']()); // obj Object
-
레퍼런스 타입 체크
// reference Type var objXReference = { base: obj Object, propertyName: 'X' }; // referenceType 값을 반환한다. GetValue(objXReference); // X function object
-
obj 객체의 A 메서드를 x 변수에 할당한다.
// global Execution Context var obj = { A: function(){ return this; } }; // x 변수 선언 var x = obj.A; console.log(x()); // global object
-
레퍼런스 타입 체크
// reference Type var objAReference = { base: obj Object, propertyName: 'A' }; // reference Type var xReference = { base: global object, propertyName: 'x' }; // referenceType 값을 반환한다. GetValue(xReference); // A function object
-
레퍼런스 타입이 아닌 함수 표현식(즉시 실행 함수)
// global Execution Context // 식별자 또는 프로퍼티 접근자가 아닌 함수 표현식 (function () { // 이 경우 레퍼런스 타입이 존재하지 않으므로, 결국 null 을 반환 후 자동으로 전역 객체로 변환된다. console.log(this); // null => global object })();
-
레퍼런스 타입 체크
// 식별자 또는 프로퍼티 접근자가 아닌 함수 표현식(즉시 실행 함수)은 reference Type 값이 존재하지 않는다.
-
함수 내부에 선언된 함수
-
A 함수 내부에 선언된 B 함수는 AO(VO) 가 갖는 속성 중 하나이다. 또한 AO(VO) 는 항상 this 값을 null 로 반환하기 때문에, 결국 B 함수 내부 this 는 global object 를 갖게된다.(AO.B() === null.B())
-
The activation object always returns as this value — null (i.e. pseudo-code AO.bar() is equivalent to null.bar()). Here again we come back to the described above case, and again, this value is set to global object.
// global execution context function A() { // function Execution Context function B() { console.log(this); // this === null => global object } B(); // AO.B() == null.B() } A();
-
-
ECStack 내부
var ECStack = [ <B> activeFunctionExecutionContext: { AO(VO): { arguments: { } }, this: null ==> global Object }, <A> functionExecutionContext: { AO(VO): { arguments: { } B: < reference to function > }, this: global Object }, globalExecutionContext: { VO: { A: < reference to function > }, this: global object } ];
-
레퍼런스 타입 체크
// reference Type var BReference = { base: null, propertyName: 'B' }; // referenceType 값을 반환한다. GetValue(BReference); // B function object
-
-
생성자 함수 호출
-
new 연산자의 객체 매커니즘에 따라 this 값은 생성된 객체로 초기화 된다.
// global Execution Context function A(){ // function Execution Context this.id = 'mohwa'; // new 연산자 + 생성자 함수를 통해 생성된 객체로 초기화된다. console.dir(this); // A object } // 객체를 생성한다. new A;
-
new 연산자 매커니즘 Pseudo-Code
function A(){ this.id = 'mohwa'; console.dir(this); // A instance } var o = New(A); console.dir(o); // A instance // new 연산자 구현 function New(constructor) { constructor = constructor || function F(){}; var o = {}; // 전달받은 생성자 함수 객체의 원형을 o 객체의 원형으로 위임한다. o.__proto__ = constructor.prototype; // 생성자 함수 객체의 this 값을 o 객체로 초기화한다. constructor.call(o); return o; }
-
-
함수 호출 시 this 값을 초기화 하는 방법
-
Function.prototype 객체 메서드인 call 과 apply 메서드를 통해, 함수 호출 시 this 값을 초기화할 수 있다.
-
call 메서드를 통해 전달된 객체로 this 값을 초기화한다.
function A(x, y){ // function execution context console.dir(this); // obj Object console.log(x); // 1 console.log(y); // 2 } var obj = { id: 'mohwa' }; // A 함수 객체의 this 값을 obj 객체로 초기화 한다. A.call(obj, 1, 2);
-
apply 메서드를 통해 전달된 객체로 this 값을 초기화한다.
function A(x, y){ console.dir(this); // obj Object console.log(x); // 1 console.log(y); // 2 } var obj = { id: 'mohwa' }; // A 함수 객체의 this 값을 obj 객체로 초기화 한다. A.apply(obj, [1, 2]);
-
-
-
-
This in JS
October 14, 2015