Deep Dive 22장 This
1. this 키워드
- 객체는 상태를 나타내는 프로퍼티와 동작을 나타내는 메서드를 하나의 논리적인 단위로 묶은 복합적인 자료구조다.
- 메서드는 자신ㅇ이 속한 택체의 상태를 변경할 수 있어야 하여 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.
- 리터럴 방식의 객체는 메서드에서 재귀적으로 참조할 수 있지만 일반적이지 않으며 바람직하지 않은 방법이다.
const circle = {
radius: 5,
getDiameter() {
return 2 * circle.radius; // 재귀
},
};
console.log(circle.getDiameter());
- 자바스크립트는 this라는 특수한 자기참조 변수를 제공한다.
- this는 js 엔진에 의해 암묵적으로 생성되며 함수를 호출하면 arguments 객체와 this가 암묵적으로 함수 내부에 전달된다.
- this가 가리키는 값인 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
2. 함수 호출 방식과 this 바인딩
- 함수의 호출 방식
- 일반함수 호출
- 메서드 호출
- 생성자 함수 호출
- Function.prototype.apply/call/bind 에 의한 간접호출
// 일반함수 호출
const foo = function () {
console.log(this);
};
foo();
/* <ref *1> Object [global] {
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
}
일반함수는 global 객체를 가리킨다.
} */
// 메서드 호출
const obj = { foo };
obj.foo(); // { foo: [Function: foo] }
// 생성자 함수 호출
new foo(); //foo {}
일반 함수 호출
- 기본적으로 this에는 전역 객체가 바인딩된다.
- strict mode가 적용되면 undefined가 바인딩 된다.
function foo() {
console.log("foo's this:", this);// global
function bar() {
console.log("bar's this:", this); // global
}
bar();
}
foo();
- 메서드 내에서 정의한 중첩 함수도 this에 전역 객체가 바인딩 된다.
- 어떤 함수라도 일반 함수로 호출되는 this에 전역 객체가 바인딩 된다.
var value = 1;
const obj = {
value: 100,
foo() {
console.log("foo's this:", this); // obj
setTimeout(function () {
console.log("callback's this:", this); // window
console.log("callback's value:", this.value); // 1
}, 100);
},
};
obj.foo();
- 메서드 내부의 중첩함수는 콜백함수의 this 바인딩을 일치시키는 방법
-
this를 변수에 할당
var value = 1; const obj = { value: 100, foo() { const that = this; setTimeout(function () { console.log("callback's that:", that); //{ value: 100, foo: [Function: foo] } console.log("callback's value:", that.value); //100 }, 100); }, }; obj.foo();
-
bind 사용
var value = 1; const obj = { value: 100, foo() { setTimeout( function () { console.log("callback's that:", this); //{ value: 100, foo: [Function: foo] } console.log("callback's value:", this.value); //100 }.bind(this), 100 ); }, }; obj.foo();
-
화살표함수 사용( 화살표 함수 내부의 this는 상위 스코프의 this를 가리킨다.)
var value = 1; const obj = { value: 100, foo() { setTimeout(() => console.log(this.value), 100); // 100 }, }; obj.foo();
-
메서드 호출
- 메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩된다.
- 메서드는 객체에 포함된것이 아닌 독립적으로 존재하는 별도의 객체다. 메서드 프로퍼티가 함수 객체를 가리키고 있다.
const person = {
name: "Yim",
getName() {
return this.name;
},
};
console.log(person.getName());
// getName을 호출한 객체는 person 이다.
const anotherPerson = {
name: "Kim",
};
anotherPerson.getName = person.getName; // 메서드 할당
console.log(anotherPerson.getName());
const getName = person.getName;
console.log(getName()); // window.name
생성자 함수 호출
- 생성자 함수 내부의 this에는 생성자 함수가 생성할 인스턴스가 바인딩된다.
- new 가없으면 일반함수처럼 this가 동작한다.
Function.prototype.apply/call/bind
- 세 메서드는 함수의 프로토타입 메서드 이기 때문에 모든 함수가 상속받아 사용할 수 있다.
- apply와 call 은 this로 사용할 객체와 argument를 인수로 받는다. apply와 call의 차이점은 apply는 argument를 배열로 받고 call은 쉼표로 구분해서 전달한다.
- bind는 this 로 사용할 객체만을 보낸다..
- apply,call 과 bind의 차이점은 함수의 호출 유무이다. bind는 함수를 호출하진 않는다.
function getThisBinding() {
console.log(arguments);
return this;
}
const thisArg = { a: 1 };
console.log(getThisBinding);
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// [Arguments] { '0': 1, '1': 2, '2': 3 }
// { a: 1 }
console.log(getThisBinding.call(thisArg, 1, "zz", 3));
// [Arguments] { '0': 1, '1': 'zz', '2': 3 }
// { a: 1 }
console.log(getThisBinding.bind(thisArg));
//[Function: bound getThisBinding] 호출이 안된다.
console.log(getThisBinding.bind(thisArg)());
// /[Arguments] {}
// { a: 1 }
Author And Source
이 문제에 관하여(Deep Dive 22장 This), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hanminss/Deep-Dive-22장-This저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)