- this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다.
- this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메소드를 참조할 수 있다.
- 자바스크립트의 this는 함수가 호출되는 방식에 따라 this에 바인딩될 값, 즉 this 바인딩이 동적으로 결정된다.
전역 객체
를 가리킨다.전역 객체
를 가리킨다.독립성
이다.함수명();
객체.메서드명()
.
또는 []
이다.obj.methodA();
=> // this === obj
obj['methodA']();
=> // this === obj
var obj1 = {
outer: function() {
console.log(this); // (1)
var innerFunc = function() {
console.log(this); // (2), (3)
}
innerFunc();
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod();
}
};
obj1.outer();
(1) : obj1, (2) : 전역객체, (3) : obj2
그런데, 개발자 입장에서 이게 쉽게 받아들여지지 않는다. 그러므로 우회할 수 있는 방법이 있다.
메서드 내부 함수에서의 this를 우회하는 방법
1. 변수를 활용하는 방법
var obj1 = {
outer: function() {
console.log(this); // (1) outer
// AS-IS
var innerFunc1 = function() {
console.log(this); // (2) 전역객체
}
innerFunc1();
// TO-BE
var self = this;
var innerFunc2 = function() {
console.log(self); // (3) outer
};
innerFunc2();
}
};
// 메서드 호출 부분
obj1.outer();
2. 화살표 함수를 활용하는 방법
- ES6에서 처음 도입된 화살표 함수는, 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다.
- 따라서 this는 이전의 값(상위 값)이 유지된다.
- ES6에서는 함수 내부에서 this가 전역 객체를 바라보는 문제 때문에 화살표 함수를 도입했다.
var obj = {
outer: function() {
console.log(this); // (1) obj
var innerFunc = () => {
console.log(this); // (2) obj
};
innerFunc();
}
}
obj.outer();
- 콜백 함수 : "어떠한 함수, 메서드의 매개변수로 넘겨주는 함수"
- 콜백 함수도 함수이기 때문에 this는 전역 객체를 참조하지만, 콜백함수를 넘겨받은 함수(ex. addEventListener)에서 콜백 함수에 별도로 this를 지정한 경우에는 예외적으로 그 대상을 참조하게 되어있다.
// 별도 지정 없음 : 전역객체
setTimeout(function () { console.log(this) }, 300);
// 별도 지정 없음 : 전역객체
[1, 2, 3, 4, 5].forEach(function(x) {
console.log(this, x);
});
// addListener 안에서의 this는 항상 호출한 주체의 element를 return하도록 설계되었음
// 따라서 this는 button을 의미함
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
console.log(this, e);
});
- 생성자 : 구체적인 인스턴스(객체)를 생성하는 함수
- 일반 함수와 동일한 방법으로 생성자 함수를 정의하고
new
연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
var Cat = function (name, age) {
this.bark = '야옹';
this.name = name;
this.age = age;
};
var choco = new Cat('초코', 7); // this : choco
var nabi = new Cat('나비', 5); // this : nabi
// 전역에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window
function square(number) {
// 일반 함수 내부에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window
return number * number;
}
square(2);
const person = {
name : 'Lee',
getName() {
// 메서드 내부에서 this는 메서드를 호출한 객체를 가리킨다.
console.log(this); // {name : 'Lee', getName : f} => person
return this.name;
}
};
console.log(person.getName()); // Lee
function Person(name) {
this.name = name;
// 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
console.log(this); // Person {name: "Lee"}
}
const me = new Person('Lee');
함수 호출 방식 | this 바인딩 |
---|---|
일반 함수 호출 | 전역 객체 |
메서드 호출 | 메서드를 호출한 객체 |
생성자 함수 호출 | 생성자 함수가 (미래에) 생성할 인스턴스 |
Function.prototype.apply/call/bind 메서드에 의한 간접 호출 | Function.prototype.apply/call/bind 메서드에 첫번째 인수로 전달한 객체 |