본문 바로가기

언어/javascript

바인딩 되지 않는 this

반응형

화살표 함수가 나오기 전까지는, 모든 새로운 함수는, 어떻게 그 함수가 호출되는지에 따라 this값을 정의했습니다.

 

이는 객체 지향 스타일로 프로그래밍할 때 별로 좋지않습니다.

function Person() {
	this.age = 0;
    
    setInterval(function growUp() {
    
    this.age++;
	}, 1000);
}

var p = new Person();

비엄격 모드에서는 setInterval 안의 this와 Person객체안의 this는 다릅니다. 

 

엄격모드란?

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

 

Strict mode - JavaScript | MDN

엄격 모드는 평범한 JavaScript 시멘틱스에 몇가지 변경이 일어나게 합니다.

developer.mozilla.org

 

ES6이전에는 이 문제를 this 값을 폐쇄될 수 있는 (비전역) 변수에 할당하여 해결했습니다.

 

function Person() {
	var that = this;
    that.age = 0;
    
    setInterval(function growUp() {
    that.age++;
   }, 1000);
}

이렇게 하는 대신에, 바인딩 함수는 적절한 this 값이 growUp() 함수에 전달될 수 있도록 생성될 수 있습니다.

 

당연한 이야기지만 function 안의 객체를 this는 참조하기 때문에 어쩔수 없다. 하지만 lo함수 화살표 함수가 나오면서 이문제는 쉽게 해결가능합니다.

 

function Person() {
	this.age = 0;
    
    setInterval(() => {
    	this.age++;
    }, 1000);
}

var p = new Perseon();

 

call 또는 apply를 통한 피호출

- 화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드 인자만 전달 할 수 있습니다. this는 무시됩니다.

 

call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출합니다.

 

call 함수 예제

call 함수는 첫번째 인자로 객체를 받는다. call을 호추라는 함수의 주어진 객체처럼 동작하도로 사용된다.

function Product(name, price) {
    this.name = name;
    this.price = price;
}

function Food(name, price) {
    Product.call(this,name,price);
    this.category = 'food';
}

console.log(new Food('cheese', 5));
// Food { name: 'cheese', price: 5, category: 'food' }
var adder = {
  base : 1,

  add : function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base : 2
    };

    return f.call(b, a);
  }
};

console.log(adder.add(1));         // 이는 2가 콘솔에 출력될 것임
console.log(adder.addThruCall(1)); // 이도 2가 콘솔에 출력될 것임

근데 this는 화살표 함수에 없기 때문에 상위의 this.base에서 바인딩 하게 된다.

 

반응형