일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
- 자료구조
- javascript
- 코드스테이츠
- OSI 7계층
- primitive type
- 백준 nodeJS
- 코드스테이츠 메인프로젝트
- 페이지네이션
- Node js
- CSS
- next/Image
- 프론트엔드
- 배열
- 이벤트 루프
- 자바스크립트
- nodejs
- 알고리즘
- input class
- 백준
- 버블정렬
- sort
- kakao map api
- Native select
- react js
- MUI
- 유데미
- 재귀함수
- 정규표현식
- JavaScript Deep Dive
- 코딩테스트
- Today
- Total
신입 개발자에서 시니어 개발자가 되기까지
[Javascript Deep Dive] 22장 this(호출 방식에 따른 this 바인딩) 본문
[Javascript Deep Dive] 22장 this(호출 방식에 따른 this 바인딩)
Jin.K 2022. 10. 27. 00:59미루고 미뤄왔던.. this 바인딩이다. 오랜만에 deep dive 책을 펼쳐 읽었다. 역시나 정리를 하면서 읽으면 시간이 아주 오래 걸린다. 포스팅까지 하면 더더욱.. 하지만 미뤄왔던 일을 하나 해치우고 나니 뿌듯하다~!~!
함수 호출 방식에 따른 this 바인딩
- 렉시컬 스코프와 this 바인딩은 결정의 시기가 다르다. 렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성
되는 시점에 상위 스코프를 결정한다. 이에 반해 this 바인딩은 함수 호출 시점에 결정된다.
① 일반 함수 호출할 때 내부에 있는 this
-전역함수, 전역함수 내 중첩함수 전부 일반함수로 호출하면 함수 내부의 this에는 전역 객체가 바인딩된다.
그러나 this는 객체의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수이므로 객체를 생성하지 않는 일반 함수에서 this는 의미가 없다. 그래서 strict mode에서는 undefined가 바인딩된다.
- 메서드 내에서 정의한 중첩함수라도 일반 함수로 호출되면 중첩 함수 내부의 this에는 전역 객체가 바인딩 된다.
- 결론 : 일반 함수로 호출된 모든 함수(중첩 함수, 콜백 함수 포함) 내부의 this에는 전역 객체가 바인딩된다.
①-1. 중첩 함수 또는 콜백 함수의 내부 this가 전역 객체를 가리키는 문제
- 중첩 함수나 콜백 함수는 보통 외부 함수를 돕는 헬퍼 함수 역할을 하므로 외부 함수의 로직을 대신하는
경우가 대부분이다. 그런데 외부 함수와 this의 바인딩이 다른 것은 헬퍼 함수로서의 동작을 어렵게 한다.
①-2.메서드의 this와 메서드 내부 중첩함수의 this 일치 시키기
1)this가 일치 안됐을 때 코드.
const obj = {
age: 32,
foo() {
console.log(this); // {age:32, foo:...}
setTimeout(function () {
console.log("setTimeout : ", this); //window
}, 200);
},
};
obj.foo();
2)this 일치
- 콜백 함수 내부에서 this 대신 test를 참조하면 된다. test는 window가 아니라 obj를 가리키고 있으니까.
const obj = {
age: 32,
foo() {
const test = this;
console.log(this); // {age:32, foo:...}
setTimeout(function () {
console.log("setTimeout : ", test.age); //32
}, 200);
},
};
obj.foo();
①-3. arrow function과의 일반 함수 호출의 차이.
-arrow function을 사용하면 this가 일치된다.
1) 예시 코드
const obj = {
age: 32,
foo() {
console.log(this);// {age:32, foo:...}
setTimeout(() => {
console.log("setTimeout : ", this); // {age:32, foo:...}
}, 200);
},
};
obj.foo();
② 객체의 메서드를 호출할 때 this
-메서드 내부의 this에는 메서드를 호출한 객체(마침표 연산자 앞에 기술한 객체)가 바인딩 된다.
-메서드를 소유한 객체가 아니라, 메서드를 호출한 객체에 바인딩 되는 것을 명심해야 한다.
1) 예시 코드
const drink = {
name: "데자와",
getName() {
return this.name;
},
};
const cafe = {
name: "루이보스",
};
cafe.getName = drink.getName;
console.log(cafe.getName());//루이보스
-이처럼 메서드 내부의 this는 메서드를 호출한 시점에 객체에 바인딩된다.
③ 생성자 함수 안에서의 this
-생성자 함수 안에서 this에는 생성자 함수가 미래에 생성할 인스턴스가 바인딩 된다.
1) 예시 코드
function study(time) {
this.time = time;
this.setTime = function () {
return this.time / 60;
};
}
let group1 = new study(120);
let group2 = new study(240);
console.log(group1.setTime());//2
console.log(group2.setTime());//4
④ Function.prototype.apply/call/bind 메서드에 의한 간접호출
-apply, call, bind 메서드는 Function.prototype의 메서드다.
④-1. apply, call 사용법
-this로 사용할 객체와 인수 리스트를 인수로 전달받아 함수를 호출.
-본질적인 기능은 함수를 호출하는 것이다. apply와 call은 함수에 인수를 전달하는 방식만 다르고, 동일하게 동작한다.
1) 예시 코드
function cook() {
let food = [];
for (let key in this) {
food.push(this[key]);
}
return food;
}
const bestFood = {
1: "제육볶음",
2: "돈까스",
3: "고기국수",
4: "함박스테이크",
};
console.log(cook.apply(bestFood));//[ '제육볶음', '돈까스', '고기국수', '함박스테이크' ]
apply의 첫 번째 인수로 전달한 객체를 함수의 this에 바인딩해준다.
- 주 용도 : 유사배열 객체에 배열 메서드를 사용할 때.
④-2. bind 사용법
-bind는 함수를 호출하지 않는다. this 바인딩이 교체된 함수를 새롭게 생성하여 반환한다.(기존의 함수 변경하는 것 아님)
console.log(cook.bind(bestFood));//[Function: bound cook]
console.log(cook.bind(bestFood)()); //[ '제육볶음', '돈까스', '고기국수', '함박스테이크' ]
⑤ 결론
- 일반 함수 호출에서 this : Window 전역 객체
- 메서드 호출에서 this : 메서드를 호출한 객체 obj를 가리킨다.
- 생성자 함수 호출에서 this : 생성자 함수가 생성한 인스턴스
- call/apply/bind : 전달인자에 의해 결정된다.
'책읽기 > Javascript Deep Dive' 카테고리의 다른 글
[Javascript Deep Dive] 42장 이벤트 루프 (2) | 2022.11.02 |
---|---|
[Javascript Deep Dive] 15장 let, const (0) | 2022.10.03 |
[Javascript Deep Dive] 24장 클로저 (1) | 2022.10.03 |
[Javascript Deep Dive] 13장 스코프 (0) | 2022.10.03 |
[Javascript Deep Dive] 10장 객체 리터럴 (0) | 2022.10.03 |