[JavaScript] This
This란?Permalink
자바스크립트에서 함수를 호출하면 그 함수에는 매개변수로 전달된 인자 외에 this
와 argument
가 내부적으로 전달된다. 그리고 이때 this
에 할당되는 값은 기본적으로 전역 객체, 즉 모든 객체의 유일한 최상위 객체인 window
이며 이는 함수를 호출한 방식에 따라 동적으로 변하게 된다.
함수 호출 방식Permalink
함수 호출 방식에는 함수 호출, 메서드 호출, 그리고 생성자 함수 호출 등이 있다.
1. 함수 호출Permalink
전역 문맥에 선언한 함수는 전역 객체의 메서드라고 생각할 수 있다.
console.log(this === window); // true
전역 문맥에서 선언한 함수의 this
도 전역 객체인 window
에 바인딩 된다.
function foo() {
console.log(this);
}
foo(); // window
중첩된 함수에서 내부 함수의 this
도 전역 객체인 window
에 바인딩 된다.
function outer() {
console.log("outer", this);
function inner() {
console.log("inner", this);
}
inner();
}
outer();
// "outer", window
// "inner", window
메서드의 내부 함수의 this
도 전역 객체인 window
에 바인딩 된다.
const value = "global";
const obj = {
value: "local",
method: function () {
function inner() {
console.log("inner", this);
console.log("value", this.value);
}
inner();
},
};
obj.method();
// "inner", window
// "value", "global"
콜백 함수의 this
도 전역 객체의 window
에 바인딩 된다.
const value = "global";
const obj = {
value: "local",
callback: function () {
setTimeout(function () {
console.log("callback", this);
console.log("value", this.value);
}, 1000);
},
};
obj.callback();
// "callback", window
// "value", "global"
이렇듯 내부 함수의 this
는 선언된 위치와 상관 없이 전역 객체 window
에 바인딩 된다.
2. 메서드 호출Permalink
만약 함수가 메서드로써 호출이 된다면 this
는 해당 메서드가 속한 객체에 바인딩 된다.
const value = "global";
const obj = {
value: "local",
method: function () {
console.log("method", this);
console.log("value", this.value);
},
};
obj.method();
// "method", obj
// "value", "local"
3. 생성자 함수 호출Permalink
함수를 new 연산자와 함께 호출하여 해당 함수를 생성자 함수로 사용하면 this
는 새로 생성한 객체에 바인딩 된다.
만약 생성자 함수에 반환문이 없는 경우, 반환문에 this
를 적어준 것과 같은 동작을 하게 되어 this
에 바인딩 된 새로 생성한 객체가 반환된다.
function Constructor(name) {
this.name = name;
}
const moon = new Constructor("Moon");
console.log(moon); // { name: "Moon" }
만약 new 연산자와 함께 함수를 호출하지 않으면 이는 일반 함수가 되기 때문에 this
가 전역 객체window
에 바인딩 되어 작동이 달라진다.
function Constructor(name) {
this.name = name;
}
const ga = Constructor("Ga");
console.log(ga); // undefined
console.log(window.name); // "Ga"
4. apply/call/bind 호출Permalink
앞서 언급한 방식들에 따라 this
가 암묵적으로 바인딩 되는 것 대신에 이 값을 직접 명시하고 싶다면 apply
와 call
을 사용하면 된다.
applyPermalink
apply
메서드는 두 개의 매개변수를 사용하는데, 첫 번째 매개변수에는 함수의 this
에 바인딩하고자 하는 객체를 입력하고 두 번째 매개변수에는 함수에 전달할 인자의 배열을 입력하면 된다.
const Constructor = function (name, age) {
this.name = name;
this.age = age;
};
const object = {};
Constructor.apply(object, ["Moon", 20]);
console.log(object); // { name: "Moon", age: 20 }
apply
를 사용함으로써 Constructor
의 this
가 object
의 this
를 가리키게 되었고, 그에 따라 인자로 전달한 "Moon"
과 20
이 object
의 name
과 age
에 할당되었다.
callPermalink
call
메서드는 apply
메서드와 기능은 거의 유사하지만 apply
메서드와 달리 매개변수로 배열이 아닌 목록이 전달된다.
const Constructor = function (name, age) {
this.name = name;
this.age = age;
};
const object = {};
Constructor.call(object, "Moon", 20);
console.log(object); // { name: "Moon", age: 20 }
마찬가지로 Constructor
의 this
가 object
의 this
를 가리키게 되어 object
의 name
과 age
에 할당되었다.
bindPermalink
bind
메서드는 매개변수로 전달된 값이 메서드가 사용된 함수의 this
에 바인딩 된 새로운 함수를 생성한다.
const user = {
name: "moon",
age: 20,
};
function info() {
console.log(this.name);
console.log(this.age);
}
const getUser = info.bind(user);
getUser(); // "moon" 20
user
객체의 값들이 info
함수의 this
에 바인딩 되어 getUser
라는 새로운 함수를 생성한 것을 확인할 수 있다.