ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코어 자바스크립트 스터디] 1주차 - this와 화살표 함수
    Javascript 2022. 6. 16. 21:58

    1. this 바인딩

    this 바인딩은 함수의 호출 방식에 따라 동적으로 결정된다

    • 자바스크립트는 함수가 "함수"로 호출되는 경우, this가 전역 객체를 가리키도록 설계되었다
    • 즉, browser 환경에서는 window, node.js 환경에서는 global 객체를 출력하게 되는 것이다
    function printThisInFunction () {
        console.log(this);
    }
    
    printThisInFunction();
    
    /*
    Window {window: Window, self: Window, document: document, name: '', location: Location, …}
    */

    • ES5 체제에서는 함수 내부에서 this를 사용할 때, 주변 LexicalEnvironment에 있는 this를 사용할 수 있도록 다양한 방법을 사용했다(call, apply, bind 등 활용)

     

    • 한편 ES6로 넘어오면서 화살표 함수가 도입 되었다. 화살표 함수를 사용하면  스코프체인상 가장 가까운 this에 접근할 수 있다. 함수 내부에는 this가 아예 존재하지 않는다
    var obj = {
    
        testFunction: function () {
    
            console.log("(a) : ", this); // (a)
    
            var normalFunction = function () {
                
                console.log("(b) : ", this); // (b)
                
            }
            
            normalFunction();
            
            var arrowFunction = () => {
    
                console.log("(c) : ", this); // (c)
                
            }
            
            arrowFunction();
        }
    }
    
    obj.testFunction();
    
    /*
    (a) :  {testFunction: ƒ}
    (b) :  Window {window: Window, self: Window, document: document, name: '', location: Location, …}
    (c) :  {testFunction: ƒ}
    */

     

    • (a): obj 내의 testFunction이 "메서드"로 호출되었으므로, 여기서 this는 obj 객체를 가리킨다
    • (b): 익명함수(normalFunction)의 경우, "함수"로 호출되었으므로, this는 전역객체인 window를 가리킨다
    • (c): 화살표 함수의 경우 스코프체인 상 가장 가까운 this를 가리킨다. 현 실행 컨텍스트에서 스코프체인상 가장 가까운 this는 obj이므로, obj로 바인딩한다

    화살표 함수를 사용하면, this를 활용해야할 때 코드를 더욱 간결하게 짤 수 있다. 화살표 함수는 또한 "콜백 함수 내부의 this 문제" 역시 해결하기 위해 설계되었다.

     


     

    2. 콜백 함수 내부의 this 문제

    콜백 함수가 일반 함수로 호출될 때, 콜백 함수의 this와 외부 함수의 this가 서로 다른 값을 가리킬 수 있다

     

    클래스 하나를 생성하고, 매서드에 콜백 함수를 일반 함수로 호출하여 보자

    class FruitMarket {
    	
        constructor() {
        	this.fruits = [];
        }
        
        addFruit(fruits) {
            
            console.log("fruits are : ", fruits);
            
        	return fruits.map(function (fruit){
                
            	this.fruits.push(fruit);
                
            });
        }
    }
    
    const fruitMarket = new FruitMarket();
    console.log(fruitMarket.addFruit(['apple', 'banana', 'grape', 'orange']));
    
    /*
    fruits are :  (4) ['apple', 'banana', 'grape', 'orange']
    
    Uncaught TypeError: Cannot read properties of undefined (reading 'fruits')
        at <anonymous>:13:15
        at Array.map (<anonymous>)
        at FruitMarket.addFruit (<anonymous>:11:20)
        at <anonymous>:20:25
    */

     

    • FruitMarket이라는 클래스의 인스턴스를 생성하고, 과일 목록이 담긴 배열을 addFruit 메서드를 사용해 추가했다
    • 그런데 제대로 콜백 함수가 실행될 때 this가 undefined로 바인딩 되어 TypeError가 발생하였다
    • console.log()로 this.fruits를 찍어보니, 같은 TypeError가 발생한다. this가 전역 객체를 바인딩한다면, 전역 객체에 fruits라는 프로퍼티가 존재하지 않기 때문에 undefined가 출력되어야 맞다. 하지만 그렇게 작동하지 않는다

     


     

    클래스 내부의 모든 코드에는 strict mode가 적용된다

     

    자바스크립트 클래스 내부의 모든 코드에 strict mode가 적용되면, 일반 함수로서 호출되는 모든 함수 내부의 this는 undefined로 바인딩된다. 이 때 화살표 함수를 사용하면 this 바인딩 문제를 쉽게 해결할 수 있다

     

    class FruitMarket {
    	
        constructor() {
        	this.fruits = [];
        }
        
        addFruit(fruits) {
            
        	return fruits.map(fruit => this.fruits.push(fruit));
        }
    }
    
    const fruitMarket = new FruitMarket(); // 인스턴스 생성
    
    fruitMarket.addFruit(['apple', 'banana', 'grape', 'orange']); // 과일 목록 추가
    
    console.log("fruits in the market: " + fruitMarket.fruits); // 결과 확인
    
    /*
    fruits in the market: apple,banana,grape,orange
    */

     

    3. 그럼 화살표 함수가 만능인가?

    아니다. 화살표 함수는 모든 상황에 사용할 수는 없다. 여기서는 MDN 문서를 참고해 간단하게 나열만 하겠다

    • 화살표 함수는 생성자로 사용할 수 없다. 즉 new 연산자를 사용하면 오류가 발생한다
    • 생성자로 사용할 수 없으므로, prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다
    • 파라미터와 화살표 사이에 개행 문자를 포함할 수 없다
    • 중복된 매개변수 이름을 선언할 수 없다

     

    4. 참고

    • 정재남, 코어 자바스크립트, 위키북스(2019)
    • 이웅모, 모던 자바스크립트 딥다이브, 위키북스(2020)

    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions

     

    화살표 함수 - JavaScript | MDN

    화살표 함수 표현(arrow function expression)은 전통적인 함수표현(function)의 간편한 대안입니다. 하지만, 화살표 함수는 몇 가지 제한점이 있고 모든 상황에 사용할 수는 없습니다.

    developer.mozilla.org

     

Designed by Tistory.