[CS] JavaScript - this

ZenTechie·2023년 5월 9일
0

Javascript

목록 보기
3/5

this

자바스크립트에서 모든 함수는 실행될 때 마다 함수 내부에 this 라는 객체가 추가된다.
arguments 라는 유사 배열 객체와 함께 함수 내부로 암묵적으로 전달되는 것이다.
그렇기 때문에 자바스크립트에서의 this 는 함수가 호출된 상황에 따라 그 모습을 달리한다.

상황1. 객체의 메소드를 호출할 경우

객체의 프로퍼티가 함수일 경우 메소드라고 칭한다. this 는 함수를 실행할 때, 함수를 소유하고 있는 객체(메소드를 포함하고 있는 인스턴스)를 참조한다.

즉, 해당 메소드를 호출한 객체로 바인딩(binding)된다.

예를 들어, A.B 를 호출할 때 B 함수 내부에서의 thisA 를 가리킨다.

var myObject = {
  name: "foo",
  sayName: function() {
    console.log(this);
  }
};
myObject.sayName();

위 코드는 Object {name: "foo", sayName: sayName()} 를 출력한다.

상황2. 함수를 호출할 경우

특정 객체의 메소드가 아니라 함수를 호출할 경우, 해당 함수 내부 코드에서 사용된 this전역객체에 바인딩(binding)된다.

예를 들어, A.B 를 호출할 때 A전역 객체가 되므로 B 함수 내부에서의 this 는 자명하게도 전역 객체에 바인딩(binding) 되는 것이다.

var value = 100;
var myObj = {
  value: 1,
  func1: function() {
    console.log(`func1's this.value: ${this.value}`);

    var func2 = function() {
      console.log(`func2's this.value ${this.value}`);
    };
    func2();
  }
};

myObj.func1();

func1 에서의 this상황 1과 같다. 그렇기 때문에myObjthis바인딩되고 myObjvalue1이 콘솔에 출력된다.
그러나 func2상황 2로 해석된다. A.B 구조에서 A 가 없기 때문에, 함수 내부에서 this전역 객체를 참조하게 되고 value100이 되는 것이다.

위 코드는,

func1's this.value: 1 func2's this.value: 100

를 출력한다.

상황3. 생성자 함수를 통해 객체를 생성할 경우

단순히 함수를 호출하는 것이 아닌, new 키워드를 통해 생성자 함수를 호출할 경우 this 는 또 다르게 바인딩 된다.
new 키워드를 통해서 호출된 함수 내부에서의 this객체 자신을 의미한다.
생성자 함수를 호출할 때의 this 바인딩은 생성자 함수가 동작하는 방식을 통해 이해할 수 있다.

new 연산자를 통해 함수를 생성자로 호출하게 되면, 일단 빈 객체가 생성되고 this바인딩 된다.
이 객체는 함수를 통해 생성된 객체이며, 자신의 부모인 프로토타입 객체와 연결되어 있다. 그리고 return 문이 명시되어 있지 않은 경우에는 this바인딩 된 새로 생성한 객체가 반환된다.

var Person = function(name) {
  console.log(this);
  this.name = name;
};

var foo = new Person("foo"); // Person
console.log(foo.name); // foo

상황4. apply, call, bind 를 통한 호출

이제까지 살펴본 상황1, 상황2, 상황3 에 의존하지 않고 this 를 자바스크립트 코드로 주입 또는 설정할 수 있다.
상황 2에서 사용했던 예제 코드를 다시 한번 살펴보자. func2 를 호출할 때, func1 에서의 this 를 주입하기 위해서 위 세가지 메소드를 사용할 수 있다.
그리고 세 메소드의 차이점을 파악하기 위해 func2파라미터를 받을 수 있도록 수정하자.

bind 메소드 사용

var value = 100;
var myObj = {
  value: 1,
  func1: function() {
    console.log(`func1's this.value: ${this.value}`);

    var func2 = function(val1, val2) {
      console.log(`func2's this.value ${this.value} and ${val1} and ${val2}`);
    }.bind(this, `param1`, `param2`);
    func2();
  }
};

myObj.func1();
// console> func1's this.value: 1
// console> func2's this.value: 1 and param1 and param2

call 메소드 사용

var value = 100;
var myObj = {
  value: 1,
  func1: function() {
    console.log(`func1's this.value: ${this.value}`);

    var func2 = function(val1, val2) {
      console.log(`func2's this.value ${this.value} and ${val1} and ${val2}`);
    };
    func2.call(this, `param1`, `param2`);
  }
};

myObj.func1();
// console> func1's this.value: 1
// console> func2's this.value: 1 and param1 and param2

apply 메소드 사용

var value = 100;
var myObj = {
  value: 1,
  func1: function() {
    console.log(`func1's this.value: ${this.value}`);

    var func2 = function(val1, val2) {
      console.log(`func2's this.value ${this.value} and ${val1} and ${val2}`);
    };
    func2.apply(this, [`param1`, `param2`]);
  }
};

myObj.func1();
// console> func1's this.value: 1
// console> func2's this.value: 1 and param1 and param2

정리

  • bind
    • bind 는 함수를 선언할 때, this 와 파라미터를 지정해줄 수 있다.
    • 각각의 파라미터를 하나씩 넘겨준다.
  • apply
    • apply 는 함수를 호출할 때 this와 파라미터를 지정해준다.
    • apply 메소드에는 첫 번째 인자로 this 를 넘겨주고 두 번째 인자로 넘겨줘야 하는 파라미터를 배열의 형태로 전달한다.
  • call
    • call 은 함수를 호출할 때 this와 파라미터를 지정해준다.
    • 각각의 파라미터를 하나씩 넘겨준다.
profile
데브코스 진행 중.. ~ 2024.03

0개의 댓글