ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Javascript this 관련
    javascript 2021. 2. 23. 14:44
    반응형

    "코어 자바스크립트" 라는 책의 내용을 위주로 작성하였고 책에서 다루지 않는 ES6 관련내용을 따로 추가하였습니다.

    www.yes24.com/Product/Goods/78586788

     

    코어 자바스크립트

    자바스크립트의 근간을 이루는 핵심 이론들을 정확하게 이해하는 것을 목표로 합니다최근 웹 개발 진영은 빠르게 발전하고 있으며, 그 중심에는 자바스크립트가 있다고 해도 결코 과언이 아니

    www.yes24.com

     

    전역 공간에서의 this

    전역공간에 this는 window(NodeJS에서는 global) 를 가리킨다. 

    console.log(this === window);     //true

    var로 전역변수를 선언하면 javascript 엔진은 이를 전역객체의 property로 할당한다.

    var a = 1;
    
    console.log(window.a);     // 1
    console.log(this.a);       // 1

    그러나 주의할 점은 const, let으로 전역변수를 선언시에는 window(global) 객체에 property로 할당하지 않는다.

    let a = 1;
    const b = 2;
    
    console.log(window.a);			//undefined
    console.log(window.b);			//undefined

     

    함수에서의 this

    function keyword로 선언하는 함수와 Arrow Function으로 선언하는 함수 2가지로 나눠서 봐야 한다.

    funcion keyword

    1. function keyword로 선언하는 함수에서는 this를 무조건적으로 binding하게 되어 있다. 명시적으로 (binding, call, apply 등) binding하지 않으면 this는 default로 window(global) 객체로 binding 된다.

    function funA(a, b) {
      console.log(this);
    }
    
    let a = 1, b = 2;
    
    funcA(a, b);		//window 객체
    
    const obj =  { // does not create a new scope
      a: function() {
        console.log(this);			//obj
        
        function b() {
        	console.log(this);		//window
        }
        b();
      }
    }
    
    obj.a();

    2. binding, call, apply 함수로 명시적으로 this를 binding해서 실행하면 this가 window가 아님을 알 수 있다.

    funcA.call({name: "Call"}, a, b);			//{name: "Call"}
    funcA.apply({name: "Apply"}, [a, b]);		//{name: "Apply"}
    
    const funcABind = funcA.bind({name: "Binding"});
    funcABind(a, b);							//{name: "Binding"}

    3. object의 맴버 함수로 선언 후 call 했을 때에는 해당 object가 this로 설정된다. "." 함수로 (예를 들어 obj.funcA()) 호출하면 해당 함수의 this는 "." 앞의 object로 설정된다.

    const obj = {
      name: "Object",
      funcA: function () {
        console.log(this);
      }
    }
    
    obj.funcA();			//{name: "Object", funcA: funcion () {...}}

    4. ES6 Class에서 this 동작

    Class의 멤버함수를 새로운 변수에 할당 후 사용하면 this가 undefined로 된다. 

    class Animal {
    	constructor() {
      	this.bite = this.bite.bind(this);
      }
      
      bite() {
      	console.log(this);
      }
      
      speak() {
        console.log(this);
      }
      
      static eat() {
        console.log(this);
      }
    }
    
    const animal = new Animal();
    animal.a = 1;
    animal.bite();		//Animal {a: 1}
    animal.speak();		//Animal {a: 1}
    Animal.eat();			//Class Animal
    
    const speak = animal.speak;
    const eat = Animal.eat;
    const bite = animal.bite;
    
    bite();						//Animal {a: 1}
    speak();					//undefined
    eat();						//undefined

    ES6 Class 문법으로 React Component를 만들 때 dom event handler에 멤버함수를 등록시 this binding을 해야 하는 원인이다.

    Arrow Function

    Arrow Function은 명시적으로 this를 binding 할수 없다. 때문에 call, apply, this 등 함수를 사용할 수 없다.

    Arrow Function에서의 this는 함수 선언 시 해당 함수가 속해 있는 scope의 this를 자동으로 binding 하게 되어 있다.

    때문에 멤버함수로 Arrow Function을 사용시 주의 해야 한다.

    const obj =  { // does not create a new scope
      a: function() {
        console.log(this);
      },
      b: () => {
      	console.log(this);
      }
    }
    
    obj.a();		//obj
    obj.b();		//window

    Class에서도 하기와 같이 따로 binding을 하지 않아도 this가 항상 해당 Class로 출력된다. 때문에 Class 문법 React Component에서 멤버함수를 Arrow Function으로 선언하면 this binding 없이도 dom event handler에 등록해도 잘 동작한다. 참고로 React Component에서 하기와 같이 멤버함수/변수 선언을 "=" 로 할수 있는것은 public class field syntax 때문이다.

     

    반응형

    'javascript' 카테고리의 다른 글

    Javascript 런타임  (1) 2022.08.29
    [Javascript] undefined 와 null  (0) 2020.12.01

    댓글

Designed by Tistory.