ES6 Arrow Function & This Test

February 18, 2016

1. 글에 대해

  • 이 글은 ES5ES6 Arrow Function 안에서 this 값이 어떤식으로 평가되는지에 대한 내용을 다루고있다.

  • 또한 모든 결과는 Chrome 브라우저를 통해 테스트된 결과입니다.

2. ES5 & this

  • this 값 초기화 테스트

    // 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

    // 버튼 객체를 생성한다.
    var btnElem = document.querySelector('#btn1');
    
    // 생성된 버튼 객체에 click 이벤트를 바인딩한다.
    btnElem.addEventListener('click', function(){
    
        // 이 경우 this 값은 target element 인 btnElem 객체를 가리킨다.
        console.log(this); // btnElem object        
    });
  • bind 함수를 통해 (바인딩된)함수 내부 this 값을 전역 스코프의 this 값으로 초기화 시킬 수 있다.

    // 버튼 객체를 생성한다.
    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 Functionthis
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 Functionthis 값(Arrow Functionthis 값을 동적 바인딩하기위한 방법)
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

관련 URL


Profile picture

Written by mohwa