this
자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수 this를 사용하여 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
자바스크립트의 this는 자바나 C++ 같은 클래스 기반 언어와는 다르게 함수 호출 방식에 의해 동적으로 바인딩 된다.
const data = {
name: 'hong',
getRole() {
return this.name + ' manager'; // 메서드를 호출한 객체를 가리킴
},
};
function Person(name) {
this.name = name;
return this.name + ' manager';
}
// 생성자 함수 내부의 this는 생성할 인스턴스를 가리킴
const person = new Person('hong');
console.log(person); // "hong manager"
function add(a, b) {
console.log(this); // 일반 함수내의 this 는 전역 객체를 가리킴, 단 strict mode 활성화 시에는 undefined를 반환
return a + b;
}
add(3, 5);
함수 호출 방식과 this 바인딩
-
일반함수 호출: window 전역객체를 바인딩
- 일반함수로 호출한 모든함수(콜백함수, 중첩함수)
const obj = { value: 50, add() { const self = this; setTimeout(() => { console.log(self.value); // 메서드 내부에서 this를 변수에 할당 후 참조하는 방식으로 객체에 접근할 수 있다. }, 100); }, }; const obj = { value: 50, add() { setTimeout( function () { console.log(this.value); }.bind(this), 100, ); }, }; const obj = { value: 50, add() { setTimeout(() => { console.log(this.value); // 화살표 함수 내부의 this는 상위 스코프의 this를 가리킴 }, 100); }, };
-
메서드 호출: 메서드를 호출한 객체를 바인딩
- 메서드는 프로퍼티에 바인딩된 함수이기 때문에 아래와 같이 호출한 객체의 this가 바인딩 되는 것이다.
- 프로토타입 메서드도 동일하게 동작한다.
const obj1 = { name: 'kim', }; const data = { name: 'hong', getRole() { return this.name + ' manager'; // 메서드를 호출한 객체를 가리킴 }, }; obj1.getRole = data.getRole; obj1.getRole(); // kim manager; const getRole = data.getRole; getRole(); // "" 메서드를 호출한 전역객체가 this에 바인딩되어 window.name이 반환됨
- 생성자 함수 호출: 생성한 인스턴스를 바인딩
-
Function.prototype.call/bind/apply: 인수에 따라 다르게 바인딩
/** * @param thisArg - this로 사용할 객체 * @param argsArray - 함수에게 전달할 인수 리스트의 배열 또는 유사 배열 객체 * @return 호출한 함수의 반환값 */ Function.prototype.apply(thisArg[, argsArray]) /** * @param thisArg - this로 사용할 객체 * @param arg1, arg2, ... - 함수에게 전달할 인수 리스트 * @return 호출한 함수의 반환값 */ Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
bind 메서드는 위의 두 메서드와는 다르게 함수를 호출하지 않고 this로 사용할 객체만 전달한다.
const person = { name: 'Lee', foo(callback) { // bind 메서드로 this를 바인딩 해줄경우 콜백함수에서 호출한 객체 자신에 접근이 가능하다 setTimeout(callback.bind(this), 100); }, }; person.foo(function () { console.log(this.name); // 일반함수로 호출될 콜백함수 내부의 this는 window 객체를 가리킨다. });