Front-end/JavaScript

JS OOP 3편 - this 바인딩(new, implicit, explicit, arrow)

파리외 개발자 2023. 2. 12. 13:46

OOP의 new연산자 this 바인딩

JS에서 클래스를 사용한 OOP방식의 코드작성에는 new 연산자를 사용해 this값을

생성되는 인스턴스에 바인딩해서 this가 인스턴스를 가리키게끔 한다.

그 외에 this를 바인딩하는 방식들이 JS에는 여러 개 존재한다.

 

Default

JS는 lexical scope를 기본적으로 따르지만 this를 계산할 때는 dynamic scope방식을 따른다.

따라서 실행 익스큐션의 this value는 작성된 위치에서 계산되는 것이 아닌

실행하는 global객체를 기본적으로 가리키게 된다.

 

new binding

//new binding this
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = new Person("Xavier", 55);
console.log(person1);

new 연산자를 사용하면 this는 생성되는 인스턴스를 가리킨다.

인자로 전달받은 값은 this의 속성들에 할당되게 되는데,

여기서 new로 인해 this는 생성되는 person1에 바인딩되어

해당 인스턴스의 속성으로 인자가 할당된다.

 

암시적 바인딩

//implicit binding
const person = {
  name: "Karen",
  age: 40,
  hi() {
    console.log("hi" + this.name);
  },
};

person.hi()

객체에 속한 메서드의 this는 전역이 아닌 해당 객체를 암묵적으로 가리킨다.

this가 person을 가리키므로 해당 객체의 name속성에 할당된 Karen을 출력한다.

 

명시적 바인딩

//explicit binding
const person3 = {
  name: "Tom",
  age: 13,
  hi: function () {
    console.log("hi" + this.setTimeout);
  }.bind(window),
};

person3.hi();

bind나 call, apply등을 사용하면 this바인딩을 명시적으로 지정할 수 있다.

암묵적으로 객체의 메서드의 this는 객체 스스로를 가리키지만

bind를 통해 window객체를 걸어주면 this는 window를 가리키게 된다.

윈도우 객체의 setTimeout함수를 불러오는 것을 확인할 수 있다.

 

arrow 함수

//arrow func
const person4 = {
  name: "kung",
  age: 22,
  hi: function () {
    var inner = () => {
      console.log("hi" + this.name);
    };
    return inner();
  },
};

person4.hi();

es6의 문법인 화살표함수는 위의 모든 법칙들을 모두 무시한다.

화살표 함수의 this는 완벽하게 lexical 하게 동작한다.

내장함수인 inner는 어휘적으로 객체의 메서드에서 작성되고 호출되었으므로

this는 해당 객체를 가리키게 된다.