this
는 js에서 함수가 호출될 때, 해당 함수의 실행문맥 (context)을 참조하는 특별한 키워드이다. this
가 가리키는 값은 함수가 어떻게 호출되었는지에 따라서 결정된다.
this
가 어떻게 설정되는지에 대한 몇가지 일반적인 규칙이 존재한다.
this
는 전역객체를 가리킨다. 브라우저에서는 window객체
가 전역 객체이다.console.log(this); // window 객체가 나온다.
this
는 전역객체 (window
혹은 global
)를 가리킨다. 하지만, strict mode에서는 undefined가 된다.function myFunction(){
console.log(this);
}
myFunction();
this
는 해당 메서드를 호출한 객체를 가리킨다.const obj = {
name : 'Alice',
greet : function(){
console.log(this.name);
}
};
obj.greet(); // 'Alice'
new
키워드와 함께 호출된 생성자 함수에서 this
는 새로 생성된 객체를 가리킨다.function myFunction(){
console.log(this.name);
}
const obj = {name : 'BOB'};
myFunction.call(obj); // 'BOB'
functionName.call(thisArg, arg1, arg2, ... );
이 외에도 call
, apply
, bind
메서드를 사용해서 this 값을 명시적으로 설정할 수 있다.
화살표함수에서는 this
가 정적으로 바인딩된다.
이것은 화살표함수가 선언될 때의 렉시컬 환경, 즉 화살표함수가 포함된 외부 스코프의 this
값을 그대로 사용한다는 것이다. 그러니까 상속
된다.
헷깔릴 수 있다.
일반함수는 호출컨텍스트에 따라서 동적으로 결정되고, 화살표함수는 선언시에 정적(상속)으로 결정된다.
중요하기 때문에 자세히 살펴보자.
const obj = {
name: 'Alice',
greet: function() {
const innerFunction = () => {
console.log(this.name);
};
innerFunction();
}
};
obj.greet(); // 'Alice'
위에서는 innerFunction이 화살표함수로 정의되어있다. 근데 화살표함수는 자신의 this
를 가지지 않는다. innerFunction 내부의 this
는 greet 메서드의 this와 동일하게 obj를 가리킨다.
따라서 this.name
은 'Alice'를 출력하게 된다.
여러가지 경우를 살펴보자.
const name = 'global';
const obj = {
name: 'Alice',
greet: function() {
console.log(this.name);
}
};
obj.greet();
// 'Alice'가 출력된다. 여기서의 this는 호출된 문맥에 따라서 결정. 그러니까 this는 obj가 된다. 그럼 obj.name은 'Alice'이다.
const name = 'global';
const obj = {
name: 'Alice',
greet: () => {
console.log(this.name);
}
};
obj.greet();
// 'global'이 출력된다. 왜냐하면 obj의 this는 window 객체이기 때문에 greet (화살표함수)의 this또한 window 객체가 된다.
const name = 'global';
const obj = {
name: 'Alice',
greet: function(){
const innerFunc = ()=>{
console.log(this.name);
}
innerFunc();
}
};
obj.greet();
// 'Alice' 가 된다. 왜냐하면 화살표함수는 선언시에 그 this가 정적으로 상속받으며 정해지고 상위스코프인 greet 함수(일반함수)의 this를 받게 된다. greet 함수의 this는 obj이다. 따라서 this.name은 obj.name이 된다.