03 this
3-1 상황에 따라 달라지는 this
3-1-1 전역공간에서의 this
- 전역 공간에서 this는 전역 객체를 가리킨다.
console.log(this === window);
console.log(this === global);
- 전역변수를 선언하면 이를 전역객체의 프로퍼티로도 할당한다.
- 처음부터 전역객체의 프로퍼티로 할당한 경우 삭제가 되지만 전역변수로 선언한 경우에는 삭제가 되지 않는다.
3-1-2 메서드로서 호출할 때 그 메서드 내부에서의 this
- 함수는 그 자체로 독립적인 기능을 수행
- 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행
var func = function (x) {
console.log(this, x);
};
func(1);
var obj = {
method: func
};
obj.method(2);
obj['method'](2);
3-1-3 함수로서 호출할 때 그 함수 내부에서의 this
- 함수에서의 this는 전역 객체를 가리킨다.
- 해당 함수를 호출하는 구문 앞에 점 또는 대괄호 표기가 있는지
var obj1 = {
outer: function () {
console.log(this);
var innerFunc = function () {
console.log(this);
};
innerFunc();
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod();
}
};
obj1.outer();
- 메서드의 내부 함수에서의 this를 우회하는 방법
var obj = {
outer: function () {
console.log(this);
var innerFunc1 = function () {
console.log(this);
};
innerFunc1();
var self = this;
var innerFunc2 = function () {
console.log(self);
};
innerFunc2();
}
};
obj.outer();
- this를 바인딩하지 않는 화살표 함수 (ES6)
var obj = {
outer: function () {
console.log(this);
var innerFunc = () => {
console.log(this);
};
innerFunc();
}
};
obj.outer();
3-1-4 콜백 함수 호출 시 그 함수 내부에서의 this
- 콜백 함수 : 함수 A의 제어권을 다른 함수(또는 메서드) B에게 넘겨주는 경우 함수 A를 콜백 함수라고 한다.
setTimeout(function () { console.log(this); }, 300);
[1, 2, 3, 4, 5].forEach(function (x) {
console.log(this, x);
};
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function (e) {
console.log(this.e);
}
3-1-5 생성자 함수 내부에서의 this
- 어떤 함수가 생성자 함수로서 호출된 경우 내부에서의 this는 곧 새로 만들 구체적인 인스턴스 자신이 된다.
3-2 명시적으로 this를 바인딩하는 방법
3-2-1 call 메서드
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func(1, 2, 3);
func.call({ x: 1 }, 4, 5, 6);
3-2-2 apply 메서드
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]);
3-2-3 call / apply 메서드의 활용
- 유사배열객체에 배열 메서드를 적용
- arguments, NodeList에 배열 메서드를 적용
- 문자열에 배열 메서드 적용
- Array.from : 유사배열객체 또는 순회 가능한 모든 종류의 데이터 타입을 배열로 전환(ES6)
3-2-4 bind 메서드
- call과 비슷하지만 즉시 호출하지는 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
func(1, 2, 3, 4);
var bindFunc1 = func.bind({ x: 1 });
bindFunc1(5, 6, 7, 8);
var bindFunc2 = func.bind({ x: 1 }, 4, 5);
bindFunc2(6, 7);
bindFunc2(8, 9);
- name 프로퍼티 : bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 bound 접두어가 붙는다.
- 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
var obj = {
outer: function () {
console.log(this);
var innerFunc = function () {
console.log(this);
};
innerFunc.call(this);
}
};
obj.outer();
3-2-5 화살표 함수의 예외사항
- 화살표 함수 내부에는 this가 아예 없고, 접근하고자 하면 스코프체인상 가장 가까운 this에 접근하므로 call/apply/bind를 적용할 필요가 없다.
var obj = {
outer: function () {
console.log(this);
var innerFunc = () => {
console.log(this);
};
innerFunc();
}
};
obj.outer();
3-2-6 별도의 인자로 this를 받는 경우 (콜백 함수 내에서의 this)
- 콜백 함수를 인자로 받는 메서드 중 일부는 추가로 this로 지정할 객체를 인자로 지정할 수 있는 경우가 있다.
- forEach, map, filter, some, every, find, findIndex, flatMap, from