복습
- 함수가 호출 되면 그때 그때 상황에 따라 this가 가리키는 객체가 결정된다.
- 이렇게 함수가 호출 될 때마다 this가 동적으로 결정되는 것을 "this가 그 객체에 binding 된다"라고 표현한다.
- 동작을 나타내는 메서드는 자신이 속한 객체의 상태, 즉 프로퍼티를 참조하고 변경할 수 있어야 한다. 그러기 위해서는 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.
this의 동적 바인딩
1. 일반 함수 호출
function func(){
console.log(this);
function func2(){
console.log(this);
}
func2();
}
func();
- 일반 함수를 호출했을 때 전역객체인 window를 바인딩하게 됨.
그렇다면 객체의 메서드와 메서드 내부 함수의 this는 어떻게 다를까?
var name = 'global var';
const obj = {
name:'Tom',
say(){
console.log('my name is ', this.name);
function say2(){
console.log('my name is ', this.name);
}
say2();
}
};
obj.say();
var name = 'global var';
const obj = {
name:'Tom',
say(){
console.log('my name is ', this.name);
const that = this;
function say2(){
console.log('my name is ', that.name);
}
say2();
}
};
obj.say();
- 화살표 함수 사용
var name = 'global var';
const obj = {
name:'Tom',
say(){
console.log('my name is ', this.name);
const say2 = ()=> {
console.log('my name is ', this.name);
}
say2();
}
};
obj.say();
- apply, call, bind와 같은 빌트인 객체 프로토타입의 메서드들을 이용
var name = 'global var';
const obj = {
name:'Tom',
say(){
console.log('my name is ', this.name);
function say2(){
console.log('my name is ', this.name);
}
say2.apply(this);
say2.call(this);
}
};
obj.say();
2. 메서드 호출
const obj = {
name:'Tom',
say(){
console.log('my name is ', this.name);
}
};
obj.say();
- say 메서드에서 this가 이미 obj로 바인딩되어 있는것처럼 보이지만 사실은 메서드가 호출될 때 정해짐.
const obj = {
name:'Tom',
say(){
console.log('my name is ', this.name);
}
};
obj.say();
const obj2 = {
name:'James',
};
obj2.__proto__.say = obj.say;
obj2.say();
- say 메서드는 obj 객체에 종속된 함수가 아니다.
- obj 객체라는 공간이 있다면, say 프로퍼티가 있고, 그 프로퍼티가 어떤 공간을 가리킨다.
- say 프로퍼티가 가리키는 공간에 함수가 정의되어 있을 것이며, say 함수의 구현을 담고 있다.
- 프로토타입에 정의된 say 메서드는 obj2.say()로 호출 될 것이고, 호출시 동적으로 this가 바인딩되기 때문에 obj2 객체가 바인딩된다.
즉 메서드가 객체 내부에 종속된 것이 아님.
3. 생성자 함수 호출
function Person(name){
this.name = name;
this.say = function(){
console.log('my name is ', this.name);
};
}
const tom = new Person('Tom');
console.log(tom)
const noTom = Person('Tom');
console.log(noTom);
4. Function.prototype.apply/call/bind 메서드에 의한 간접호출
var fire = 'fail..';
const thisObj = { fire : 'fire!' };
function func(a,b,c){
console.log(a,b,c, this.fire);
}
console.log(func(3,2,1));
console.log(func.apply(thisObj, [3,2,1]));
console.log(func.call(thisObj, 3, 2, 1));
console.log(func.bind(thisObj));
const bindFunc = func.bind(thisObj, 100);
bindFunc(2, 1);
자바스크립트 this
함수 호출 방식과 this 바인딩
this 바인딩 정리
이렇게 유용한 정보를 공유해주셔서 감사합니다.