JavaScript에서의 this는 선언된 시점에 따라 달라진다. 사전적인 의미로는 현재 실행중인 함수가 속한 객체, 또는 자신이 생성할 인스턴스를 나타낸다. 따라서 함수를 호출한 시점에 this가 결정된다고 볼 수 있다.
this는 다음의 특징을 갖는다고 할 수 있다.
- this는 모든 곳에 존재한다.
- 함수 안의 this는 어떻게 함수를 부르는가에 달렸다.
- 화살표 함수 안의 this는 선언될 때 결정된다.
this
실행 결과
콘솔 창에서 this를 입력했을 때에 window가 반환되는 것은 함수 밖의 전역 실행 문맥에서 this를 호출했기 때문에 현재 코드가 실행중인 javascript의 런타임, 브라우저를 반환한 것이다.
function foo(){
this.name="FOO";
return this;
}
const bar=new foo();
bar
실행 결과
new 연산자를 사용하여 생성자 함수방식으로 인스턴스를 생성한 경우, this는 new로 만들어진 빈 객체를 가리키게 된다.
function foo(){
console.log(this);
}
실행 결과
foo라는 함수를 만들어 실행시키면 foo()는 전역에서 실행되는 것이므로 실행 중인 현재의 인스턴스인 window를 가리킨다. 하지만
const greet={
name:"Hoonystory",
hello(){
console.log(this);
console.log("Hello, "+this.name);
}
}
greet.hello();
실행 결과
위의 코드에서는 hello 메서드를 호출했을 때, this.name은 현재 greet 객체 내의 hello를 실행 중이므로 console.log(this)를 실행시켰을 때의 현재 객체인 greet를 반환하고 this.name을 호출하면 greet의 name을 반환한다.
const baz={
nums: [1,2,3,4,5],
readNums() {
this.nums.forEach(function(num) {
console.log(num);
console.log(this);
});
}
}
baz.readNums();
실행 결과
객체 내의 메서드를 통해 실행된 고차함수의 경우 각 매개변수마다 콜백 함수를 실행해주며, 콜백 함수는 일반 함수이므로 this를 호출했을 때 window를 반환한다.
const baz={
nums: [1,2,3,4,5],
readNums() {
this.nums.forEach(function(num) {
console.log(num);
console.log(this);
},this);
}
}
baz.readNums();
실행 결과
콜백 함수 다음의 참조할 인자로 객체를 전달해주면 this를 호출했을 때, 참조하는 객체를 반환한다.
this가 특정한 대상을 가리키도록 하는 것을 바인딩이라고 한다. 바인딩으로 사용하는 함수는 call, apply, bind가 있다.
function foo(){
console.log(this);
}
const obj={
name: "honystory",
}
foo.call(obj);
실행 결과
foo는 this를 출력하는 함수로 일반적으로 실행할 경우, 전역에서 실행되어 window를 반환할 것이다. function.call을 통해 this를 지정해주면 foo.call(obj)를 실행했을 때, foo는 지정된 this인 obj를 출력한다.
function foo(a, b){
this.num = this.num + a + b;
console.log(this.num);
}
const obj={
num: 5,
}
foo.apply(obj,[1,2]);
실행 결과
apply는 call과 기능적으로 동일하나, 인자를 전달받을 때, call은 각각의 인자를 개별로 전달받지만 apply는 array 하나를 받는다.
const foo={
list: ["a","b"],
getList(){
setTimeout(function(){
console.log(this.list);
},2000);
}
}
foo.getList();
실행 결과
위의 코드는 2초 뒤 foo의 getList를 실행하는 함수이다. 객체인 foo안에서 실행되기 때문에 this.list를 호출하면 ["a","b"]를 반환해야 하지만 undefined를 반환한다. setTimeout은 비동기 함수이므로 getList가 결과를 반환할 당시의 this는 window가 되기 때문이다.
const foo={
list: ["a","b"],
getList(){
setTimeout(() => {
console.log(this.list);
},2000);
}
}
foo.getList();
실행 결과
화살표 함수를 통해 선언할 경우, this는 선언된 시점의 객체를 가리킨다. 위 함수를 실행하면 원래의 의도대로 2초 뒤, foo의 list를 반환한다. 이는 화살표 함수는 자신의 this를 가질 수 없기 때문에 자신의 상위의 렉시컬 범위(lexical scope)에서 this를 검색해서 사용하기 때문이다.