JavaScript에서의 this와 this 바인딩
흔한 객체지향 언어에서의 this
this
는 Java와 같은 객체지향 언어에서 주로 이 인스턴스(즉, 자신)를 가리키기 위해 사용한다. 아래 코드와 같이.
class Person {
private String name;
Person(String name) {
this.name = name;
}
}
위 예제는 Java에서의 this
의 용례를 보여주기 위한 코드이다. Java에서 this
는 주로 매개변수와 인스턴스 자신의 프로퍼티(멤버) 변수의 이름이 같을 경우 이를 구분하기 위해 사용한다.
JavaScript에서의 this
그러나, JavaScript에서의 this
는 함수 호출을 어떻게 하느냐(선언이 아님!!)에 따라 다른 객체들이 바인딩된다.
this
는 기본적으로 전역객체를 참조한다.
전역 함수는 물론이거나와, 그 함수의 내부에 있는 함수까지도this
는 전역객체를 참조한다.
this
를 생성자 함수에서, 혹은 객체의 메소드에서 사용하는 경우가 아니면, this
는 전역객체를 참조한다. 브라우저에서는 window
를 참조하게 된다.
그냥 함수를 호출했을 때의 this
function Person(name) {
this.name = name; // this === window
}
const me = Person('hoondev');
console.log(me); // undefined
console.log(name); // hoondev
console.log(this); // window 객체
console.log(this.name); // hoondev
이번에는 생성자 함수로서가 아니라, 그냥 함수의 호출로서 사용하였다. 그러므로 this
는 자연스레 전역객체를 참조하게 되었다. 따라서, name
은 전역변수로서 선언이 된 것이다. Person 함수의 리턴값이 없으므로 undefined
이다.
일반 함수의 내부 함수에서의 this
function func() {
console.log(this); // window 객체
function nestedFunc() {
console.log(this); // window 객체
}
nestedFunc();
}
func();
내부 함수에서도 this
는 외부 함수가 아닌 전역 객체를 참조한다.
메소드의 내부 함수에서의 this
const obj = {
text: 'hoondev',
func: function() {
console.log(this); // obj 객체
console.log(this.text); // hoondev
function nestedFunc() {
console.log(this); // window
console.log(this.text); // undefined
}
nestedFunc();
}
};
객체의 함수, 즉 메소드를 호출하는 경우, 그 메소드의 this
는 해당 메소드를 프로퍼티로 가지는 객체를 참조한다.
그래서, func에서의 this는 obj를 가리킨다.
그러나, 메소드의 내부 함수에서의 this는 전역 객체를 참조한다.
생성자 함수를 호출했을 때 this
function Person(name) {
this.name = name; // this === window
}
const me = new Person('hoondev');
console.log(me.name); // hoondev
console.log(name); // ReferenceError: name is not defined
const me2 = Person('hoondev');
console.log(me2.name); // ReferenceError: name is not defined
console.log(name); // hoondev
함수를 생성자로서 사용하는 경우, this
는 여느 객체지향 언어와 같이 자기 자신을 참조한다.
콜백함수에서의 this
let a = 1;
const obj = {
let a = 1;
func: function() {
setTimeout(function() {
console.log(this); // window
console.log(this.a); // 1
}, 100);
}
}
obj.func();
this 바인딩
this
는 함수 호출 패턴에 따라 결정된다고 하였다. 그러나 이를 무시하고, this
가 무엇을 가리키는지 명시적 바인딩을 해줄 수 있다. 그러나 이 바인딩 방식은 Arrow Function에서는 적용할 수 없다.
apply
this
에 특정 객체를 바인딩하고, 바인딩한 그 함수를 호출한다.
const School = function (name, pos) {
this.name = name;
this.pos = pos;
}
const obj = {};
School.apply(obj, ['Namsan Mid-School', 'Busan']);
console.log(obj); // { name: 'Namsan Mid-School', pos: 'Busan' }
call
apply
와 동일하지만, 두 번째 인자로 넘겨주는 arguments를 배열의 형태가 아니라 각각 전달해준다.
const School = function (name, pos) {
this.name = name;
this.pos = pos;
}
const obj = {};
School.call(obj, 'Namsan Mid-School', 'Busan');
console.log(obj); // { name: 'Namsan Mid-School', pos: 'Busan' }
bind
bind
에 인자로 전달한 객체가 this
에 바인딩되고, 바인딩된 그 함수를 리턴한다. 리액트의 Class Component에서 많이 사용한다.
const obj = {};
const Home = function() {
...
}.bind(obj);
'공부 > JavaScript' 카테고리의 다른 글
ES6에서 Arrow Function 사용하기 (0) | 2020.06.26 |
---|---|
ES6에서 let/const로 Block-scoped 변수 선언하기 (0) | 2020.06.26 |
JavaScript에서 var를 사용하면 안되는 이유 (0) | 2020.06.26 |
JavaScript ECMAScript란? (0) | 2020.06.26 |
ES6에서 배열을 활용하는 다양한 방법 (0) | 2020.06.25 |
댓글
이 글 공유하기
다른 글
-
ES6에서 Arrow Function 사용하기
ES6에서 Arrow Function 사용하기
2020.06.26 -
ES6에서 let/const로 Block-scoped 변수 선언하기
ES6에서 let/const로 Block-scoped 변수 선언하기
2020.06.26 -
JavaScript에서 var를 사용하면 안되는 이유
JavaScript에서 var를 사용하면 안되는 이유
2020.06.26 -
JavaScript ECMAScript란?
JavaScript ECMAScript란?
2020.06.26