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