일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 하위 컴포넌트에 prop 전달
- 자율 주행
- 고정밀 지도
- js bind
- 컴포넌트 합성
- javascript
- js call apply bind
- React Child Component
- HD Map
- js apply
- react
- react props
- js call
- Prop Drilling
- Javascript this undefined
- context api
- 중첩된 prop
- 고정밀지도
- Today
- Total
simkkong
[JavaScript] this와 call, apply, bind 본문
this 는 현재 객체를 가리킨다. 정확히는 메서드를 호출할 때 사용된 객체를 의미한다.
즉 아래와 같이 animal 객체 안에서 run 메서드가 실행이 되면 run을 실행한 animal 객체를 가리키며, 전역에서 호출하게 되면, 글로벌한 window 객체를 가리킨다.
let animal = {
name: '코끼리',
run() {
console.log(this.name);
}
}
animal.run() // '코끼리' (this == animal)
//or
class animal {
constructor() {
this.name = '코끼리';
}
run() {
console.log(this.name);
}
}
const elephant = new animal()
elephant.run() // '코끼리' (this == animal)
console.log(this); // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
쉽게 생각하면, .run() 메서드의 '점 앞'에 있는 animal 이 객체로 지정된 것이라고 생각하면 된다.
console.log 안의 this 는, 지정된 객체가 없기에 전역 객체를 참고하게 되어 window 를 가리키는 것이다.
동일한 메서드를 사용하더라도, 자바스크립트 런타임에 의해 this가 가리키는 곳이 달라진다.
let elephant = { name: '코끼리' };
let rabbit = { name: '토끼' };
function sayName() {
console.log(this.name);
}
elephant.run = sayName;
rabbit.run = sayName;
// 'this'는 '점(.) 앞의' 객체를 참조하기 때문에
// this 값이 달라짐
elephant.run(); // '코끼리' (this == elephant)
rabbit.run(); // '토끼' (this == rabbit)
※ 화살표 함수는 this 를 갖지않기에, 화살표 함수 내에서 this를 사용하면, 외부에서 this를 찾게된다.
const zoo = {
name: '동물원',
animals: ['코끼리', '토끼'],
animalsRun() {
this.animals.forEach(
animal => console.log(`${this.name}에 있는 동물: ${animal}`)
);
},
};
zoo.animalsRun();
// 동물원에 있는 동물: 코끼리
// 동물원에 있는 동물: 토끼
화살표 함수는 forEach 에서 사용을 했기에, this가 animalsRun 메서드를 가리켰어야 했으나, 외부 값인 this 를 가리키게 되므로, zoo 를 가리키게 된다.
만약, animal 의 run 메서드를 변수에 할당한 뒤, 실행하게 되면 어떻게 될까?
let animal = {
name: '코끼리',
run() {
console.log(this.name);
}
}
const elephant = animal.run;
elephant(); // undefined
위와 같이 this는 ainmal 을 가리키지 않고 undefined 가 뜬다. run을 실행시 '점 앞' 에 있는 animal이 아닌, elephant 에 따로 할당되어 실행되었기 때문이다. 결국 this는 window를 가리키고, window.name 이 실행되기에 undefined가 뜨게된다.
이렇게 this 가 가리키는 객체가 무엇이냐에 따라, 좀 더 코드를 유연하게 짤 수 있게된다.
call, apply, bind 를 활용하면 this가 가리키는 객체를 변경할 수 있다.
call 의 경우 아래와 같은 문법을 갖는다.
func.call(context, arg1, arg2, ...)
func.call(context, ...args);
실행할 함수의 뒤에 .call 을 붙이고, call 의 첫 번째 인수가 this=context 이며 나머지 arg1, arg2.... 들은 실행할 함수 func 들의 인수들이 된다.
function sayName(sound) {
console.log(`${this.name}의 울음소리: ${sound}`);
}
const elephant = { name: '코끼리' };
const wolf = { name: '늑대' };
// call의 첫 번째 인수인 this 영역에 가리키고자 하는 객체를 넣습니다.
sayName.call(elephant, '뿌우우'); // '코끼리의 울음소리: 뿌우우' (this == elephant)
sayName.call(wolf, '아우우'); // '늑대의 울음소리: 아우우' (this == wolf)
apply의 경우 call 과 유사하다. 아래와 같은 문법을 갖는다.
func.apply(context, args)
apply와 call의 차이점은, 인수를 따로 따로 받을지 아니면 유사 배열 형태(ex arguments, Array) 로 받을지의 차이점이다.
function fruitBasket(args) {
console.log('바구니에 들은 과일은: ', ...args);
}
let applyWrapper = function() {
return fruitBasket.apply(this, arguments);
};
let callWrapper = function() {
return fruitBasket.call(this, ...arguments);
};
applyWrapper(['사과', '배', '체리']);
callWrapper(['사과', '배', '체리']);
bind 의 경우, this를 변경을 하지만 함수를 직접 실행하지 않고 반환을 한다. call과 apply의 경우 함수를 직접 실행한다.
bind는 말 그대로 함수의 this 를 변경한 후 함수를 반환해준다.
function sayName(sound) {
console.log(`${this.name}의 울음소리: ${sound}`);
}
const elephant = { name: '코끼리' };
let elephantSay = sayName.bind(elephant, '뿌우우');
elephantSay() // '코끼리의 울음소리: 뿌우우' (this == elephant)
참고사이트
https://ko.javascript.info/call-apply-decorators
call/apply와 데코레이터, 포워딩
ko.javascript.info
https://www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd
'Develop > JavaScript' 카테고리의 다른 글
[JavaScript] Currying (커링) (0) | 2022.12.28 |
---|---|
[JavaScript] 이터러블 프로토콜을 따른 map의 다형성 (0) | 2020.04.12 |
[JavaScript] 호이스팅이란? (0) | 2020.04.05 |