this용법에 대해서

자바스크립트에선 함수를 실행하거나 ES6 이후에 등장한 블럭({})을 생성하면 실행 컨텍스트가 생기고, 이 실행 컨텍스트에는 1.Variable Enviroment, 2.Lexical Enviroment, 3.thisBinding 정보들이 담겨져 있게 됩니다.

1. Varialbe Enviroment

Variable Enviroment는 2번의 초기 상태를 snap-shot한 객체로, 초기의 Lexical Enviroment 상태를 저장하는 객체입니다. 함수가 실행되면서, 스크립트를 실행하면서 Lexical Enviroment안에 프로퍼티로 저장된 값들이 변화할 수 있기 때문에 변화를 감지하기 위해 초기 상태를 저장하는게 아닐까 싶습니다.

2. Lexical Enviroment

Lexical Enviroment안에는 환경 레코드 객체와 외부 환경 참조에 대한 정보가 저장되어있습니다. 환경 레코드 안에는 해당 스코프 안에서 선언된 식별자들에 대한 정보가 저장되어있습니다. 처음에 식별자들에 대한 정보를 얻기 위해 자바스크립트 엔진은 호이스팅이라는 개념을 사용해서 위에서 아래로 해당 스코프를 한 번 쭉 읽고나서 선언한 식별자들, 함수들을 환경 레코드 객체의 프로퍼티로 저장하게 됩니다(여기서 할당한 값들은 아직 저장하지 않습니다).

외부 환경 참조는 현재 함수가 어디서 실행되었는지, 스크립트가 어디서 부터 생성되었는지에 대한 정보가 저장되어 있습니다. 가령 중첩 객체이거나, 함수 안에서 실행한 함수의 경우 상위 스코프로의 접근이 가능한 것은 바로 외부 환경 참조에 현재 상태가 저장되어있기 때문이라고 볼 수 있습니다.

3. thisBinding

이번 장에서 확인 할 this용법에 관련한, 현재 this가 무엇을 가리키고 있는지에 대한 정보를 저장합니다. 그렇다면 this가 생성될 때의 상황을 살펴보면 이해가 쉽겠습니다.

함수를 실행하는 방법

1. 일반 함수로 실행

function func() {
  console.log(this);
  return ;
}
func(); // window

임의의 함수 선언식으로 선언한 func가 있을 때, func()를 통해 함수를 실행하면 이는 그냥 아무것도 없이 함수 자체를 실행한것입니다. 위에서 함수를 실행하면 실행 컨텍스트가 생성되면서 여러 값들이 저장된다고 했는데, 함수를 그냥 실행하게 되면 this의 값은 전역 객체(window)를 참조하게 됩니다.

2. 메서드로써 실행

메서드는 객체 안에 있는 함수로, 객체명.함수명 형태로 .이 붙어있는 형태로 함수를 호출하는 경우입니다.

const obj = {
  func() {
    console.log(this);
    return ;
  },
  sub: {
    subFunc() {
      console.log(this);
      return ;
    }
  }
}
obj.func(); // (1) obj
obj.sub.subFunc(); // (2) sub

.이 붙은 형태로 함수를 호출하는, 메서드로써 함수를 호출하게 되면 this값은 .앞에 작성한 객체를 참조하게 됩니다.

위 코드의 결과를 확인해보면 (1)의 결과는 obj객체가, (2)의 결과는 sub객체가 나타나는것을 알 수 있습니다.

3. apply/call/bind

apply/call/bind는 명시적으로 this값을 개발자가 원하는 객체로 지정할 수 있도록 도와주는 메서드입니다. 명시적으로 this값을 지정하기때문에 this값에 따른 혼란을 줄일 수 있겠습니다. 혹은 callback함수로써 함수를 전달할 경우 이 메서드들을 사용하여 this값을 기억하도록 할 수 있죠

4. new 연산자 - 생성자 함수

function Person(name,age) {
  this.name = name,
  this.age = age,
  // return 문이 없음을 유의
}
  
function PersonReturn(name, age) {
  this.name = name,
  this.age = age,
  
  return {
    name: "고릴라",
    age: 13
  }
}
  
const 영희 = new Person("영희", 23); // (1)
const 의섭 = new Person("의섭", 26); // (2)
  
const 고릴라 = new PersonReturn("원숭이", 31);
console.log(고릴라.name); // 고릴라

생성자 함수로 객체를 생성하면 this의 값은 새로 생성된 인스턴스를 가리키게 됩니다. 즉 (1)의 this는 영희를 가리키게 되고, (2)의 this는 의섭을 가리키게 되는 것 입니다.

생성자 함수를 사용할 때 주의해야 할 점이 하나 있는데 이는 return문을 작성하지 않는다는 것 입니다.

생성자 함수는 암묵적으로 새로 생성된 객체를 참조하는 this를 return 하는데, 개발자가 직접 return 문을 작성하게 된다면 어떤 경우에는 this가 return되지 않고 무시되고맙니다.

this가 무시되는 경우는 바로 return문에 객체 타입을 return했을 때 입니다. return문에 원시 타입을 return하면 해당 return 은 무시되지만 객체 타입을 return하게 되면 this자체가 무시되기때문에 이를 유의해서 사용합시다.

좋은 웹페이지 즐겨찾기