[JavaScript] this 바인딩
자바스크립트의 this는 함수가 호출되는 방식에 따라 this 바인딩이 동적으로 결정된다.
함수 호출방식에따라 this가 어떻게 바인딩 되는 지 살펴보자.
1.일반함수 호출
1
2
3
4
5
6
|
function func() {
console.log(this);
}
func(); //window
|
cs |
전역함수, 중첩함수, 콜백함수이든 일반함수로 호출하면 this에는 전역 객체가 바인딩된다.
중첩함수, 콜백함수의 경우 this가 해당객체가 아닌 전역객체를 바인딩함으로써 동작에 어려움이 발생할 수 있다.
이 경우에는 this를 명시적으로 바인딩할 수 있는 메서드들을 활용하기도 한다. this 바인딩의 일치를 위한 메서드들은 여기서 자세히 다루지는 않겠다.
2.메서드 호출
메서드 호출방식은 객체이름.메서드(); 방식으로 호출되는 것을 말한다.
메서드 내부에서는 this를 해당 객체에 바인딩한다. 다음 예제와 같은 방식이다.
1
2
3
4
5
6
7
|
const data = {
age: 20,
getAge() {
return this.age;
}
};
console.log(data.getAge()); //20
|
cs |
객체 data 안의 메서드인 getAge를 data.getAge(); 방식으로 호출하면 this는 data객체에 바인딩된다.
우리는 객체 안의 메서드를 다른 객체의 프로퍼티에 할당하기도 하고 일반변수에 할당할 수 있다.
이 경우에는 this가 어떻게 바인딩 될까?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
const data = {
age: 20,
getAge() {
return this.age;
}
};
console.log(data.getAge());
//새로운 객체
const anotherData = {
age: 30
};
//새로운 객체에 기존 객체의 메서드 할당
anotherData.getAge = data.getAge;
//해당 메서드를 호출한 객체인 anotherData에
console.log(anotherData.getAge()); //30
|
cs |
일단 새로운 객체에 기존 객체의 메서드를 할당해준 경우에도 메서드를 호출한 객체에 따라서 this가 바인딩된다. 애초에 getAge는 data라는 객체 안의 메서드이기는 하지만 별도로 존재하는 하나의 객체이기도하다. 따라서 다른 객체에 할당되더라도 getAge라는 객체를 가리키는 프로퍼티가 있는 객체가 하나 더 늘어난 것 뿐이다.
1
2
3
4
5
6
7
8
9
|
const data = {
age: 20,
getAge() {
return this.age;
}
};
const getAge = data.getAge;
console.log(getAge()); //window
|
cs |
반면에 변수에 메서드를 할당하면 data안의 메서드로 존재하던 getAge를 복사하여 꺼내온 것이 된다. 이를 일반함수로 호출하면 당연히 전역객체를 가리키고 있다.
3. 생성자 함수 호출
생성자 함수는 객체를 생성하는 함수를 말한다. 보통 함수이름의 첫글자를 대문자로 선언하고, new 연산자와 함께 호출하는 방식이다. 이러한 생성자 함수 내부의 this는 다음 코드에서 객체를 선언하는 순간 해당 객체에 바인딩된다.
즉, 생성자 함수 내부의 this는 미래에 생성할 인스턴스를 바인딩한다. new 연산자로 호출하지 않으면 일반적인 함수의 호출로 생성자 함수의 동작이 아니게된다.
1
2
3
4
5
6
7
8
9
10
11
12
|
function Person(age) {
this.age = age;
this.getAge = function () {
return this.age-(this.age%10)+"대입니다.";
}
}
const Lee = new Person(28);
const Kim = new Person(15);
console.log(Lee.getAge()); //20대입니다.
console.log(Kim.getAge()); //10대입니다.
|
cs |
이외에도 제로초님의 블로그 게시글을 참조하면서 this에 대해 이해하는데 도움을 얻었으므로 추가적인 링크를 남긴다.
https://www.zerocho.com/category/JavaScript/post/5b0645cc7e3e36001bf676eb