메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있습니다. 모든 메서드가 그런 건 아니지만, 대부분의 메서드가 객체 프로퍼티의 값을 활용합니다.
이때 '점 앞’의 this
는 객체를 나타냅니다. 정확히는 메서드를 호출할 때 사용된 객체를 나타내죠.
user.sayHi()가 실행되는 동안에 this
는 user
를 나타냅니다.
let user = {
name: "John",
age: 30,
sayHi() {
*// this는 현재 객체를 나타냅니다.
console.log(this.name);*}
};
user.sayHi(); // John
this
를 사용하지 않고 외부 변수를 참조해 객체에 접근하는 것도 가능합니다.
let user = {
name: "John",
age: 30,
sayHi(){
console.log(user.name) // 'this' 대신 'user'를 이용함
}
}
user.sayHi() // john
user는 전혀 다른 값으로 덮어썼다고 가정해 봅시다.
sayHi()는 원치 않는 값(null)
을 참조할 겁니다.
예시:
let user = {
name: "John",
age: 30,
sayHi() {
console.log( user.name ); // Error: Cannot read property 'name' of null
}
}
let admin = user;
user = null; // user를 null로 덮어씁니다.
admin.sayHi(); // sayHi()가 엉뚱한 객체를 참고하면서 에러가 발생했습니다.
alert
함수가 user.name
대신 this.name
을 인수로 받았다면 에러가 발생하지 않았을 겁니다.
자바스크립트의 this
는 다른 프로그래밍 언어의 this
와 동작 방식이 다릅니다.
자바스크립트에선 모든 함수에 this
를 사용할 수 있습니다.
아래와 같이 코드를 작성해도 문법 에러가 발생하지 않습니다.
function sayHi() {
alert( this.name );
}
this
값은 런타임에 결정됩니다. 컨텍스트에 따라 달라지죠.
동일한 함수라도 다른 객체에서 호출했다면 'this’가 참조하는 값이 달라집니다.
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// 별개의 객체에서 동일한 함수를 사용함
user.f = sayHi;
admin.f = sayHi; // 'this'는 '점(.) 앞의' 객체를 참조하기 때문에
// this 값이 달라짐
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (점과 대괄호는 동일하게 동작함)
자유로운
this
가 만드는 결과
다른 언어를 사용하다 자바스크립트로 넘어온 개발자는 this
를 혼동하기 쉽습니다. this
는 항상 메서드가 정의된 객체를 참조할 것이라고 착각하죠. 이런 개념을 'bound this
'라고 합니다.
자바스크립트에서 this
는 런타임에 결정됩니다. 메서드가 어디서 정의되었는지에 상관없이 this
는 ‘점 앞의’ 객체가 무엇인가에 따라 ‘자유롭게’ 결정됩니다.
이렇게 this
가 런타임에 결정되면 좋은 점도 있고 나쁜 점도 있습니다. 함수(메서드)를 하나만 만들어 여러 객체에서 재사용할 수 있다는 것은 장점이지만, 이런 유연함이 실수로 이어질 수 있다는 것은 단점입니다.
자바스크립트가 this
를 다루는 방식이 좋은지, 나쁜지는 우리가 판단할 문제가 아닙니다. 개발자는 this
의 동작 방식을 충분히 이해하고 장점을 취하면서 실수를 피하는 데만 집중하면 됩니다.
화살표 함수는 일반 함수와는 달리 ‘고유한’ this
를 가지지 않습니다. 화살표 함수에서 this
를 참조하면, 화살표 함수가 아닌 ‘평범한’ 외부 함수에서 this
값을 가져옵니다.
아래 예시에서 함수 arrow()
의 this
는 외부 함수 user.sayHi()
의 this
가 됩니다.
let user = {
firstName: "보라",
sayHi() {
function arrow(){
alert(this.firstName);
arrow();
}
}
};
user.sayHi(); // undefined // this === sayHi
let user = {
firstName: "보라",
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // 보라 // this === user
별개의 this
가 만들어지는 건 원하지 않고, 외부 컨텍스트에 있는 this
를 이용하고 싶은 경우 화살표 함수가 유용합니다. 이에 대한 자세한 내용은 별도의 챕터, 화살표 함수 다시 살펴보기에서 다루겠습니다.
this
로 객체를 참조합니다.this
값은 런타임에 결정됩니다.this
를 사용할 수 있습니다. 다만, 함수가 호출되기 전까지 this
엔 값이 할당되지 않습니다.object.method()
같이 ‘메서드’ 형태로 호출하면 this
는 object
를 참조합니다.this
를 가지지 않는다는 점에서 독특합니다. 화살표 함수 안에서 this
를 사용하면, 외부에서 this
값을 가져옵니다.