2 분 소요

this

this는 함수를 호출하는 객체를 의미합니다.

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다. 또한 엄격 모드와 비엄격 모드에서도 일부 차이가 있습니다.

대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정됩니다. 실행중에는 할당으로 설정할 수 없고 함수를 호출할 때 마다 다를 수 있습니다. ES5는 함수를 어떻게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드를 도입했고, ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했습니다(이는 렉시컬 컨텍스트안의 this값을 유지합니다).

function menuGlobal() {
  console.log("오늘 저녁은 " + this.name);
}

let myDinner = {
  name: "김치찌개",
  menu: menuGlobal,
};

let yourDinner = {
  name: "된장찌개",
  menu: menuGlobal,
};

myDinner.menu(); // "오늘 저녁은 김치찌개"
yourDinner.menu(); // "오늘 저녁은 된장찌개"

일반적으로 this의 값은 자동으로 할당되지만, 상황에 따라 제어할 수 있어야 합니다.

call()

call 메서드는 this의 값을 바꿀 수도 있고, 함수를 실행할 때 사용할 인수도 전달할 수 있습니다.

function menuGlobal(item) {
  console.log("오늘 저녁은 " + item + this.name);
}

let myDinner = {
  name: "김치찌개",
};

let yourDinner = {
  name: "된장찌개",
};

menuGlobal.call(myDinner, "묵은지"); // "오늘 저녁은 묵은지김치찌개"
menuGlobal.call(yourDinner, "삼겹살"); // "오늘 저녁은 삼겹살된장찌개"

apply()

apply 메서드는 함수를 실행할 때 인수를 배열로 묶어 한번에 전달합니다.

function menuGlobal(item1, item2) {
  [item1, item2].forEach(function (el) {
    console.log("오늘 저녁은 " + el + this.name);
  }, this);
}

let myDinner = {
  name: "김치찌개",
};

let yourDinner = {
  name: "된장찌개",
};

menuGlobal.apply(myDinner, ["묵은지", "삼겹살"]); // "오늘 저녁은 묵은지김치찌개" "오늘 저녁은 삼겹살김치찌개"
menuGlobal.apply(yourDinner, ["두부", "애호박"]); // "오늘 저녁은 두부된장찌개" "오늘 저녁은 애호박된장찌개"

call()과 apply()의 차이

call은 함수를 실행할 때 전달할 인수를 하나 하나 전달한다면 apply는 전달할 인수를 배열로 묶어 한번에 전달합니다. 그래서 인수를 두개만 사용합니다. 인수를 배열로 보낸다는 점 빼고는 call과 apply는 동일한 기능을 수행합니다.

bind()

bind 메서드는 es5에서 추가되었습니다. this 값을 어디서 사용하든 호출 객체가 바뀌지 않게 고정시켜버립니다.

function menuGlobal(item) {
  console.log("오늘 저녁은 " + item + this.name);
}

let myDinner = {
  name: "김치찌개",
};

let yourDinner = {
  name: "된장찌개",
};

let menuGlobalForMe = menuGlobal.bind(myDinner);
let menuGlobalForYou = menuGlobal.bind(yourDinner);

menuGlobalForMe("묵은지"); // "오늘 저녁은 묵은지김치찌개"
menuGlobalForYou("삼겹살"); // "오늘 저녁은 삼겹살된장찌개"

myDinner.menuMine = menuGlobalForYou;
myDinner.menuMin("묵은지"); // "오늘 저녁은 묵은지된장찌개"

화살표 함수와 this

화살표 함수의 this는 일반적인 this처럼 함수를 호출한 객체를 할당하지 않고, 바로 상위 스코프의 this를 할당합니다.

function menuGlobal(item1, item2) {
  console.log(this);
  /*
    [object Object] {
    	name: "김치찌개"
    }
    */
  [item1, item2].forEach((el) => {
    console.log("오늘 저녁은 " + el + this.name);
  });
}

let myDinner = {
  name: "김치찌개",
};

let yourDinner = {
  name: "된장찌개",
};

menuGlobal.apply(myDinner, ["묵은지", "삼겹살"]); // "오늘 저녁은 묵은지김치찌개" "오늘 저녁은 삼겹살김치찌개"

forEach문 안의 this는 전역을 바라보고 있다. 하지만 forEach문 안의 함수를 화살표 함수로 만들어줌으로써 상위 스코프의 this로 바라보게 바꿨다. 이게 바로 화살표 함수 안에서 사용하는 this의 특징이다.

댓글남기기