1. 글에 대해
-
이 글은 ES5 및 ES6 Arrow Function 안에서 this 값이 어떤식으로 평가되는지에 대한 내용을 다루고있다.
-
또한 모든 결과는 Chrome 브라우저를 통해 테스트된 결과입니다.
2. ES5 & this
-
this 값 초기화 테스트
```javascript // A 함수 객체를 선언한다. function A() { function B() { // this 는 undefined 로 초기화되며, undefined 는 this 로 평가될 수 없으므로, 암묵적으로 global Object 로 변환된다. console.log(this); // global Object } // AO 에 포함된 내부 함수를 호출한다. B(); // AO.B(); // 초기화된 this 값을 반환한다. return this; } // this 는 undefined 로 초기화되며, undefined 는 this 로 평가될 수 없으므로, 암묵적으로 global Object 로 변환된다. console.log(A()); // global Object // this 는 생성된 인스턴스로 초기화된다. console.log(new A()); // A Object // this 는 null 로 초기화되며, null 은 this 로 평가될 수 없으므로, 암묵적으로 global Object 로 변환된다. console.log(A.call(null)); // global Object // this 는 전달된 {x: 1} 객체로 초기화된다. console.log(A.call({x: 1})); // Object {x: 1} // this 는 전달된 {x: 2} 객체로 초기화된다. console.log(A.apply({x: 2})); // Object {x: 2} // this 는 전달된 {x: 2} 객체로 초기화된다. console.log(A.bind({x: 3})()); // Object {x: 3} ```
-
바인딩된 익명 함수 내부에서의 this 값
```javascript // 버튼 객체를 생성한다. var btnElem = document.querySelector('#btn1'); // 생성된 버튼 객체에 click 이벤트를 바인딩한다. btnElem.addEventListener('click', function(){ // 이 경우 this 값은 target element 인 btnElem 객체를 가리킨다. console.log(this); // btnElem object }); ```
-
bind 함수를 통해 (바인딩된)함수 내부 this 값을 전역 스코프의 this 값으로 초기화 시킬 수 있다.
```javascript // 버튼 객체를 생성한다. var btnElem = document.querySelector('#btn1'); // 생성된 버튼 객체에 click 이벤트를 바인딩한다. btnElem.addEventListener('click', function(){ // 이 경우 this 값은 bind 함수를 통해 초기화된 this 값을 가리킨다. console.log(this); // global object }.bind(this)); ```
-
this 값 초기화 테스트 in Strict Mode
-
Strict Mode 에서는 this 값이 null, 또는 undefined 인 경우, 암묵적으로 global Object 로 변환되지 않는다.
// A 함수 객체를 선언한다. function A() { // Strict Mode 선언 'use strict'; function B() { // this 는 undefined 로 초기화된다. console.log(this); // undefined } // AO 에 포함된 내부 함수를 호출한다. B(); // AO.B(); // 초기화된 this 값을 반환한다. return this; } // this 는 undefined 로 초기화된다. console.log(A()); // undefined // this 는 global object 로 초기화된다. console.log(this.A()); // this 는 생성된 인스턴스로 초기화된다. console.log(new A()); // A Object // this 는 null 로 초기화된다. console.log(A.call(null)); // global Object // this 는 전달된 {x: 1} 객체로 초기화된다. console.log(A.call({x: 1})); // Object {x: 1} // this 는 전달된 {x: 2} 객체로 초기화된다. console.log(A.apply({x: 2})); // Object {x: 2} // this 는 전달된 {x: 2} 객체로 초기화된다. console.log(A.bind({x: 3})()); // Object {x: 3}
-
-
this 값 초기화 테스트 in Object
-
객체 메서드에서의 this 는 해당 메서드를 내부 프로퍼티로 소유한 객체를 가리킨다.
var A = { x: function(){ var B = function(){ // this 는 undefined 로 초기화되며, undefined 는 this 로 평가될 수 없으므로, 암묵적으로 global Object 로 변환된다. console.log(this); // global Object } // AO 에 포함된 내부 함수를 호출한다. B(); // AO.B(); // 초기화된 this 값을 반환한다. return this; } }; // 이 경우 this 는 해당 함수를 내부 프로퍼티로 소유한 객체를 가리킨다. console.log(A.x()); // A Object
-
3. ES6 Arrow Function & this
-
Arrow Function 은 자신만의 this, arguments, super, new.target 이 할당되지 않는다.
-
Arrow Function 의 this 값은 함수가 위치한 지점을 둘러싼, 전역/함수 스코프의 this 값을 가리키며, 바인딩된 후 변하지 않는다.
// global execution context // Arrow Function 을 할당한다. var A = () => { // A function execution context var B = () => { // B function execution context // 이 경우 this 는 (B)함수를 둘러싼, (A)함수 스코프의 this(global Object) 값으로 초기화된다. console.log(this); } B(); // 초기화된 this 값을 반환한다. return this; }; // this 는 global object 로 초기화된 후 변하지 않는다. console.log(A()); // global Object // this 는 global object 로 초기화된 후 변하지 않는다. console.log(this.A()); // global Object // new 연산자를 통해 새로운 인스턴스 생성 시 에러가 발생한다. try { console.log(new A()); } catch(e){ // Uncaught TypeError: () => this is not a constructor console.log(e.message); } // this 는 global object 로 초기화된 후 변하지 않는다. console.log(A.call(null)); // global Object // this 는 global object 로 초기화된 후 변하지 않는다. console.log(A.call({x: 1})); // global Object // this 는 global object 로 초기화된 후 변하지 않는다. console.log(A.apply({x: 2})); // global Object // this 는 global object 로 초기화된 후 변하지 않는다. console.log(A.bind({x: 3})()); // global Object
-
바인딩된 익명 (Arrow)함수 내부에서의 this 값
// 버튼 객체를 생성한다. var btnElem = document.querySelector('#btn1'); // 생성된 버튼 객체에 click 이벤트를 바인딩한다. btnElem.addEventListener('click', () => { // 이 경우 arrow function 의 this 값은 해당 함수를 둘러싼 전역 스코프의 this 값으로 초기화된다. console.log(this); // global Object // 버튼 객체를 통해 명시적으로 접근한다. console.log(btnElem); });
-
함수 객체 내부에서의 Arrow Function 의 this 값
function A(){ // arrow function var B = () => { // 이 경우 this 는 (B)함수를 둘러싼, (A)함수 스코프의 this(global Object) 값으로 초기화된다. console.log(this); // global Object }; B(); // 초기화된 this 값을 반환한다. return this; } // this 는 global Object 로 초기화된다. A();
-
생성자 함수 객체 내부에서의 Arrow Function 의 this 값(Arrow Function 의 this 값을 동적 바인딩하기위한 방법)
function A(){ // arrow function var B = () => { // 이 경우 this 는 (B)함수를 둘러싼, (A)함수 스코프의 this(A Object) 값으로 초기화된다. console.log(this); // A Object }; B(); // 초기화된 this 값을 반환한다. return this; } // this 는 생성된 인스턴스로 초기화된다. console.log(new A()); // A Object
-
객체 메서드에서의 this 는 해당 메서드를 둘러싼, 전역 스코프의 this 값으로 초기화된다.
var A = { normalMethod: function(){ return this; // A object }, arrowMethod: () => { return this; // global object } }; // 이 경우 this 는 해당 함수를 내부 프로퍼티로 소유한 객체를 가리킨다. console.log(A.normalMethod()); // A Object // 이 경우 this 는 (arrowMethod)함수를 둘러싼, 전역 스코프의 this(global Object) 값으로 초기화된다. console.log(A.arrowMethod()); // global Object
-
Arrow Function 내부에서의 this 값 변경
var A = { arrowMethod: () => { var bindFn = function(){ console.log(this); // A object }.bind(A)(); return this; } }; console.log(A.arrowMethod()); // global Object
-
그 밖의 테스트
// 객체를 반환하기 위해서는 괄호 연산자 또는 return 문을 사용해야한다. { let a = () => {x: 1 }; console.log(a()); // undefined } { let a = () => ({x: 1}); console.log(a()); // {x: 1} object } { let a = () => { return {x: 1}; }; console.log(a()); // {x: 1} object } // IIFE(즉시 실행 함수) 는 아래와 같이 표현될수 있다. console.log((() => 1)()); // 1