JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작한다.
자바스크립트에서 this는 런타임에 결정이 되는것이다.
이러한 특징은 함수(메서드)를 하나만 만들어 여러 객체에서 재사용할 수 있다는 것은 장점이 존재하지만, 이런 유연함이 실수로 이어질 수 있다.
따라서 this의 동작 방식을 충분히 이해하고 장점을 취하면서 실수를 피하려고 노력해야한다.
대부분의 메서드는 객체 프로퍼티의 값을 활용한다.
이때 메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있다.
let user = {
name: "John",
age: 30.
sayHi() {
alert(this.name);
// 'this'는 현재 객체를 나타낸다.
}
};
user.sayHi();
user.sayHi()가 실행되는 동안 this는 객체(user)를 나타낸다.
물론 this를 사용하지 않고 외부 변수를 참조해 객체에 접근하는 것도 가능하다.
let user = {
name: "John",
age: 30,
sayHi() {
alert(user.name); // 'this' 대신 'user'를 이용함
}
};
하지만 이 경우 예상치 못한 에러가 발생할 수 있다.
만약에 user를 복사해 다른 변수에 할당하고, user는 다른 값으로 덮어썼다고 가정해 보면,
sayHi()는 원치 않는 값(null)을 참조할 것이다.
let user = {
name: "John",
age: 30,
sayHi() {
alert( user.name ); // Error: Cannot read property 'name' of null
}
};
let admin = user;
user = null; // user를 null로 덮어 씀.
admin.sayHi();
자바스크립트의 this는 다른 프로그래밍 언어의 this와 동작 방식이 다르다.
자바스크립트에서는 모든 함수에 this를 사용할 수 있다.
function sayHi() {
alert(this.name);
}
위와 같이 코드를 작성해도 문법 에러가 발생하지 않는다.
-> 컨텍스트에 따라 달라진다.
동일한 함수라도 다른 객체에서 호출했다면, '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 (점과 대괄호는 동일하게 동작함)
obj.f()를 호출했다면 this는 f를 호출하는 동안의 obj인것이다.
화살표 함수는 일반 함수와는 달리 '고유한' this를 가지지 않는다.
화살표 함수에서 this를 참조하면, 화살표 함수가 아닌 '평번한' 외부 함수에서 this값을 가져온다.
let user = {
firstName: "보라",
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // 보라
이때의 arrow()의 this는 외부함수 user.sayHi()의 this가 된다.
별개의 this가 만들어지는 건 원치않고, 외부 컨텍스트에 있는 this를 이용하고 싶은 경우 화살표 함수가 유용하게 사용할 수 있다.