정재남,『코어자바스크립트』를 읽고 정리한 내용입니다. 이해가 부족한 부분은 책과 동일하게 작성하였습니다.
이전글에서 상황별로 this에 어떤 값이 바인딩되는지 살펴봤지만 이런 규칙을 깨고 this에 명시적으로 별도의 대상을 바인딩 하는 방법도 있다!
함수를 실행하는 방법에 function()
이외에 call()
,apply()
메서드를 사용해서 함수를 즉시 실행할 수 있다. this의 값을 한 문맥에서 다른 문맥으로 넘기려면 .call과 .apply를 사용해야한다.
💡 call()나 apply()의 첫번째 매개변수로 객체를 제공하면 this가 그 객체에 묶인다.
call메서드는 첫 번째 인자를 제외한 나머지 모든 인자들을 호출할 함수의 매개변수로 지정
var obj = {a: 'Custom'};
var a = 'Global';
function whatsThis() {
return this.a;
}
whatsThis(); // 'Global'
whatsThis.call(obj); // 'Custom'
whatsThis.apply(obj); // 'Custom'
apply메서드는 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정
function add(c, d) {
return this.a + this.b + c + d;
}
var o = {a: 1, b: 3};
// 이어지는 인수들은 함수 호출에 사용할 매개변수
add.call(o, 5, 7); // 16
// 두 번째 매개변수는 배열,
// 각 요소를 함수 호출에 사용
add.apply(o, [10, 20]); // 34
1) 유사배열객체에 배열 메서드를 적용
:객체에는 배열 메서드를 직접 적용할 수는 없다. 그러나 키가 0 또는 양의 정수인 프로퍼티가 존재하고 lenth프로퍼티의 값이 0또는 양의 정수인 객체, 즉 배열의 구조와 유사한 객체의 경우(유사배열객체) call 또는 apply메서드를 이용해 배열 메서드를 빌려 쓸 수 있다.
유사배열객체에는 call/apply 메서드를 이용해 모든
2) 생성자 내부에서 다른 생성자를 호출
:생성자 내부에서 다른 생성자와 공통된 내용이 있을 경우 call 또는 apply메서드를 이용해 다른 생성자를 호출하면 간단하게 반복을 줄일 수 있다.
3) 여러 인수를 묶어 하나의 배열로 전달하고 싶을 때 - apply활용
여러 개의 인수를 받는 메서드에게 하나의 배열로 인수들을 전달하고 싶을 때 apply
메서드 사용
var numbers = [10,20,3,16,45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max,min); //45 3
ES6에서 Spread Operator를 사용하면 apply적용하는 것보다 더 간단하게 구현 가능
var numbers = [10,20,3,16,45];
var max = Math.max.apply(...numbers);
var min = Math.min.apply(...numbers);
console.log(max,min); //45 3
bind
메서드가 호출되면 새로운 함수를 반환한다. 받게되는 첫 번째 인자의 value로는 this키워드를 설정하고 이어지는 인자들은 바인드된 함수의 인수에 제공된다.
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81 - 함수의 메서드이므로 전역 스코프가 아닌 부모 obj에서 호출됐음
var retrieveX = module.getX;
retrieveX();
// 9 반환 - 함수가 전역 스코프에서 호출됐음 (주의)
// module과 바인딩된 'this'가 있는 새로운 함수 생성
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
화살표 함수에서의 this는 자신을 감싼 정적 범위(lexical context)이다. 즉 이 함수 내부에는 this가 아예 없고, 접근하려면 scope체인상 가장 가까운 this에 접근한다.
var obj = {
i:10,
b: () => console.log (this.i,this), //undefined, window
c: function() {
console.log(this.i, this) //10, obj
}
}
크게 아래의 두 가지 상황에서 각 경우에 this가 무엇일지 예측해보는 연습이 필요하다.
[참고자료]
정재남, 『코어자바스크립트』, 위키북스(2019)
MDN - JavaScript, this
https://velog.io/@heo-mk/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%ED%84%B0%EB%94%94-%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-3%EC%9E%A5-this
https://velog.io/@nayeon/Javascript%EC%97%90%EC%84%9C%EC%9D%98-this-%EC%99%80-call-apply-bind-%EB%A9%94%EC%84%9C%EB%93%9C