10. this (전역공간 this, 함수 this, 메서드 this)
1.this(정의, 활용방법, 바인딩, call, apply, bind)
- 다른 객체지향 언어에서의 this는 클레스로 생성한 인스턴스
- JS에서는 this가 어디에서나 사용될 수 있음
1. 상황에 따라 달라지는 this
우리가 하고있는것은 실행 컨텍스트임을 잊지 말자. ✔ VE ✔ LE ✔ ThisBindings |
- 1. this는 실행 컨텍스트가 생성될 때 결정됨.
즉, this는 함수를 호출할 때 결정된다.
- a. 전역공간에서의 this
- 1. 전역 공간에서 this는 전역 객체를 가리킨다.
- 2. 런타임 환경에 따라 this는 window(브라우저 환경) 또는 global(node 환) 를 각각 가리킨다.
우선 확인해보자.
- 브라우저에서는 아래와 같이 확인할 수 있다.
검색창에 console.log(this)를 치니 window가 나왔다. 여기서 this는 window 객체라는 것을 알 수 있다.
이번에 노드환경에서 살펴보겠다.
vscode에 들어가서 터미널에 node라고 치면 > 가 나오는 것을 볼 수 있다.
그럼 거기에 this라고 치고 살펴보면
이렇게 object [global]을 볼 수 있는데, 제일 밑에 this === global을 치게 되면 true가 나온다.
이렇게 전역환경에서 this는 브라우저 환경에서는 window 객체, node 환경에서는 global 객체인 것을 볼 수 있다.
2. 함수 vs 메서드
- 상당히 비슷해 보이지만 엄연한 차이가 존재한다.
- 기준은 '독립성'
- 메서드는 혼자서 실행X, 실행의 주체가 있어야함.
함수
- 호출의 주체 X
- this → 전역개체
메서드
- 호출의 주체 O
- this → 호출의 주체
예시
//메서드 vs 함수
//case1 : 함수
//호출 주체를 명시할 수 없기 때문에 this는 전역 객체를 의미
var func = function (x) {
console.log(this,x);
};
func(1); //object[global] {...} 1
함수 같은 경우 호출의 주체가 없기 때문에 바로 this로 전역개체를 가리킴으로써 global이 나온다.
//case2 : 메서드
//호출 주체를 명시할 수 있기 때문에 this는 해당 객체(obj)를 의미
//obj는 곧 {method: f}를 의미
var obj = {
method: func,
};
obj.method(2); //{method:f}2
메서드인 경우 호출 주체가 있기 때문에 해당 객체인 obj를 가리킨다.
함수로서의 호출과 메서드로서의 호출 구분 기준 : . [ ]
//this에는 호출을 누가 했는지에 대한 정보가 담긴다.
var obj = {
methodA: function() { console.log(this)},
inner: {
methodB: function() {console.log(this)},
}
};
obj.methodA(); //this === obj
obj['methodA'](); //this === obj
obj.inner.methodB(); //this === obj.inner
obj.inner['methodB'](); //this === obj.inner
obj['inner'].methodB(); //this === obj.inner
obj['inner']['methodB'](); //this === obj.inner
함수로서의 호출할 때 그 내부에서의 this
- a. 함수 내부에서의 this
i. this는 지정되지 않음(호출 주체X)
ii. this가 지정되지 않은 경우, this는 전역 객체를 의미
iii. 함수로서 '독립적'으로 호출할 때는 this는 항상 전역객체를 가리킨다. 는 것을 주의
- b. 메서드의 내부함수에서의 this
i. 예외는 없다. 메서드의 내부라고 해도, 함수로서 호출한다면 this는 전역 객체를 의미
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.outer()로 호출되기 때문에 메서드로서의 호출이다.
//2번째는 innerFunc()로 호출되기 때문에 함수로서의 호출이다.
//3번쨰는 obj2.innerMethod()로 호출되기 때문에 메서드로서의 호출이다.