this는 가지고 있는 메소드가 속해있는 객체를 가리키도록 만든 예약어라고 할 수 있다.
tihs는 객체 명의 변경에 관계없이 항상 메소드가 속해있는 객체를 바라본다.
보통 대부분의 언어에서는 this가 위 설명처럼 작동한다.
하지만 함수와 객체의 관계가 느슨한 자바스크립트에서는 this는 우리가 이해할 수 없는 방향으로 작동하고는 한다.
간단한 예시 코드들을 보면서 this가 어떻게 동작하는지 알아보려고 한다.
우선,
JavaScript에서 this는 기본적으로 window이다.
node.js 환경에서 실행 시 this는 global이다.
function f1() {
return this;
}
// 브라우저
f1() === window; // true
// Node.js
f1() === global; // true
strict 모드인 경우 undefined 이다.
ES2015 모듈에서는 strict 모드가 자동 적용된다.
function f2() {
"use strict"; // 엄격 모드 참고
return this;
}
f2() === undefined; // true
function a() {
console.log(this);
}
a();
// 출력: window 객체
const obj = {
name: 'ksg',
sayName() {
console.log(this.name);
}
}
obj.sayName();
// 출력: ksg
// 함수 생성자
function Human(name) {
this.name = name;
}
new Human('ksg');
// Human {name: 'ksg'}
아래 예시에서는 함수를 호출하는 호출자는 전역이므로 this는 window를 가리키고 있다.
const sayN = obj.sayName;
sayN();
// 출력: undefined (window.name이 출력됨)
bind
, apply
, call
함수를 사용
function sayName() {
console.log(this.name);
}
sayName();
// 출력: undefined
sayName.bind({name: 'ksg'})();
// 출력: ksg
sayName.apply({name: 'ksg'});
// 출력: ksg
sayName.call({name: 'ksg'});
// 출력: ksg
화살표 함수의 경우에는 기본적으로 부모 스코프를 가리킨다.
아래 예시의 경우에는 부모 스코프가 전역이기 때문에 호출 시 this는 window가 된다.
const obj = {
name: 'ksg',
sayName: () => {
console.log(this.name);
}
}
obj.sayName();
// 출력: undefined
아래의 경우는 inner() 호출 시 this를 바꾸어주는 행동을 하지 않았기 때문에 this는 window를 가리키고있다.
const obj = {
name: 'ksg',
sayName() {
console.log(this.name);
function inner() {
console.log(this.name);
}
inner();
}
}
// 이 경우 스코프 체인 inner -> sayName -> anonymous로 형성
obj.sayName();
// 출력: ksg
// 공백 (inner() 결과)
아래 예시의 경우에는 inner가 화살표 함수로 구현되어 있기 때문에 inner에서 사용한 this는 호출자인 obj의 name을 가리키게 된다.
const obj = {
name: 'ksg',
sayName() {
console.log(this.name);
const inner = () => {
console.log(this.name);
}
inner();
}
}
obj.sayName();
// 출력: ksg
// ksg
JavaScript에서는 기본적으로 this는 window를 가리키고있다.
bind
, apply
, call
함수를 사용하여 this를 임의로 할당이 가능하다.
화살표 함수로 구현된 경우 this는 호출 시점의 호출자를 가리킨다.