: 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기참조변수.
const circle = {
radius : 5,
getDiameter(){
return 2 * circle.radius;
}
};
console.log(circle.getDiameter()); // 10
객체리터럴(↑) 방식으로 작성한 위의 코드를 아래와 같이 생성자 함수(↓)방식으로 작성했을 때,
function Circle(radius){
????.radius = radius;
}
Circle.prototype.getDiameter = function(){
return 2 * ????.radius;
};
const circle = new Circle(5);
생성자 함수를 정의하는 시점이 인스턴스 생성하기 이전이기 때문에 우리는 .radius
가 참조해야하는 식별자를 확인할 수 없다. ( ???? 부분에 넣을 부분 )
그래서 this 바인딩이 필요하다.
: this + 바인딩(식별자와 값을 연결)
⇒ 함수를 호출함으로서 this가 가리키는 객체를 결정( 연결 )하는 것.
같은 함수라도 각각 실행되는 환경이 다르다.
- 변수에 저장되는 함수
- 함수의 인수로 전달되는 함수
- 반환값으로 사용되는 함수
- 단독으로 호출되는 함수
- 객체 내 메서드로 호출되는 함수
👉🏻 각각의 함수가 가리키는 this가 다르다.
⭐ 어떤 실행환경에서, 어떤 객체에 의해 호출되는 지에 따라 this가 달라진다.
⇒ 함수가 호출되는 방식에 따라 this 바인딩이 동적으로 결정된다.
// 전역
console.log(this) // window
// 일반함수 ==> 전역 객체 window를 가리킨다.
function square(number){
console.log(this); // window
return number * number;
}
square(2);
function foo(){
'use strict'; // => this에 ~~window가 아닌~~ undefined가 바인딩 된다.
console.log("foo's this : ", this); // undefined
}
foo();
var value = 1;
const obj = {
value : 100,
foo(){
console.log(this); // { value : 100, foo : 𝑓 }
console.log(this.value); // 100
function bar(){
console.log(this); // window
console.log(this.value); // 1
}
bar();
}
};
d
obj.foo();
var value = 1;
const obj = {
value : 100,
foo(){
console.log(this); // { value : 100, foo : 𝑓 }
console.log(this.value); // 100
setTimeout( function bar(){
console.log(this); // window
console.log(this.value); // 1
},100);
}
};
obj.foo();
어떠한 함수라도 일반함수로 호출되면 this에 전역객체가 바인딩 된다.
⇩
중첩함수 or 콜백함수 = 외부 함수를 돕는 헬퍼 함수
⇩
외부함수의 메서드의 this ≠ 중첩함수 혹은 콜백함수의 this
⇩
헬퍼함수로 동작하기 어려워짐
1. this 바인딩을 변수에 할당하기
```jsx
var value = 1;
const obj = {
value : 100,
foo(){
console.log(this); // { value : 100, foo : 𝑓 }
const that = this;
setTimeout( function bar(){
console.log(that.value); // 100
},100);
}
};
obj.foo();
```
2. Function.prototype.apply / call / bind 메서드 사용하기
= 콜백함수에 명시적으로 this를 바인딩하는 방법
```jsx
var value = 1;
const obj = {
value : 100,
foo(){
setTimeout( function bar(){
console.log(this.value); // 100
}.bind(this),100);
}
};
obj.foo();
```
3. 화살표함수 사용하기
```jsx
var value = 1;
const obj = {
value : 100,
foo(){
setTimeout(()=> console.log(this.value),100); // 100
}
};
obj.foo();
```
: 메서드 내부의 this에는 메서드를 호출한 객체, 마침표 연산자 앞에 기술한 객체가 바인딩된다. 메서드를 소유한 객체가 아닌 메서드를 호출한 객체 에 바인딩 된다는 점을 주의 !
const person = {
name <: 'Lee',
getName(){
return this.name;
}
};
console.log(person.getName()); // 'Lee'
getName 프로퍼티가 가리키는 함수 객체는 person 객체에 포함된 것이 아니라 별도의 객체로 getName프로퍼티가 함수를 그저 가리키고 있을 뿐이다.
const anotherPerson = {
name : 'Kim'
};
//다른 객체의 프로퍼티에 할당
anotherPerson.getName = person.getName;
//다른 객체의 메서드가 될 수 있으며
console.log(anotherPerson.getName()); //Kim
// 변수에 할당되어 일반함수로 호출될 수도 있다.
const getName = person.getName;
console.log(getName()); // ''
프로토 타입 메서드 내부에서 사용된 this도 메서드를 호출한 객체에 바인딩 된다.
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return this.name
};
const me = new Person('Lee');
console.log(me.getName()); // Lee
Person.prototype.name = 'Kim';
console.log(Person.prototype.getName()); // Kim
function Circle(radius){
this.radius = radius;
this.getDiameter = function(){
return 2 * this.radius;
};
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20
Function.prototype.apply(thisArg[,argsArray])
// thisArg = this로 사용할 객체
// argsArray = 함수에게 전달할 인수 리스트의 **배열** or **유사배열객체**
Function.prototype.call(thisArg[,arg1[,arg2[,...]]])
// thisArg = this로 사용할 객체
// arg1,arg2, ... = 함수에게 전달할 인수 **리스트**
⇒ 인수를 전달하는 방식만 다를 뿐 동일하게 동작한다.const person = {
name : 'Lee',
foo(callback){
setTimeout(callback,100);
}
};
person.foo(function(){
console.log(`Hi! I'm ${this.name}.`); // Hi! I'm .
});
// 콜백함수가 일반함수라 this가 window
const person = {
name : 'Lee',
foo(callback){
setTimeout(callback.bind(this),100);
// bind메서드로 callback함수의 내부의 명시적으로 this바인딩.
}
};
person.foo(function(){
console.log(`Hi! I'm ${this.name}.`); // Hi! I'm Lee.
});
함수 호출방식에 따른 this 바인딩
일반 함수 호출 ⇒ 전역객체
메서드 호출 ⇒ 메서드를 호출한 객체
생성자 함수 호출 ⇒ 생성자 함수가 생성할 인스턴스
Function.prototype.apply/call/bind
메서드에 의한 간접 호출
⇒ Function.prototype.apply/call/bind 메서드에 첫번째 인수로 전달한 객체