this에 관해 쉽게 잘 설명되어 있는 글이 있어 번역하며 공부해보았다.
영알못이기 때문에 잘못 번역한 곳이 있을 수도 있다..
this에 관한 자바스크립트의 몇 가지 규칙
this는 몇 가지 규칙에 따라 함수 내부에서 무엇을 카르키고 있는지 결정된다.
this가 무엇인지 결정하는 것은 생각보다 간단하다. 가장 중요한 규칙은 함수가 호출된 위치, 호출된 사이트를 검사하여 함수가 호출될 때 결정된다는 것이다.
우선순위에 따라 이러한 규칙을 따른다.
규칙 1
함수를 호출할 때 new 키워드가 사용되면, 해당 함수 내부에 있는 this는 완전히 새로운 객체이다.
functtion ConstructorExample() {
console.log(this); // {}
this.value = 10;
console.log(this); // { value: 10 }
}
new ConstructorExample();
new 키워드에 관한 정보가 필요하다면 아래의 글을 읽어 볼 것!
https://codeburst.io/javascripts-new-keyword-explained-as-simply-as-possible-fec0d87b2741
Javascript’s “new” Keyword Explained as Simply as Possible
Normal Function Call
codeburst.io
규칙 2
함수를 호출할 때 apply, call, bind가 사용된다면, 해당 함수의 내부에 있는 this는 인수로 전달되는 개체이다.
function fn() {
console.log(this);
}
var obj = {
value: 5
};
var boundFn = fn.bind(obj);
boundFn(); // { value: 5 }
fn.call(obj); // { value: 5 }
fn.apply(obj); // { value: 5 }
규칙 3
함수가 메서드로 호출되는 경우(점 표기법을 사용하여 함수를 호출하는 경우) 해당 함수 내부의 this는 함수가 속성인 개체이다.
쉽게 말하자면 .으로 찍힌 쪽의 왼쪽에 있는 객체가 this이다. (ƒ는 코드 블럭 내부의 함수를 상징한다.)
var obj = {
value: 5,
printThis: function() {
console.log(this);
}
};
obj.printThis(); // { value: 5, printThis: ƒ }
규칙 4
함수가 자유 함수로 호출되는 경우(조건이 없는 채로 호출되었을 때), this는 전역 객체임을 의미한다. 브라우저에서는 window가 되겠다.
function fn() {
console.log(this);
}
// 만약 브라우저에서 불릴 시
fn(); // Window { stop: ƒ, open: ƒ, alert: ƒ, .... }
* 이 규칙은 규칙 3과 같은데, 차이점은 메서드로 선언되지 않은 함수는 자동으로 전역 객체인 window의 속성이 된다는 것이다.
따라서 이것은 암시적으로 메서드 호출이다. fn()을 호출하면, window.fn()으로 해석되므로 규칙 3과 같은 이야기이며, window가 되는 것이다.
console.log(fn == window.fn); // true
규칙 5
위의 규칙이 여러 개 적용되는 경우 더 높은 규칙이 우선 적용되며 이 값을 설정한다.
규칙 6
함수가 ES2015 화살표 함수인 경우 위의 모든 규칙을 무시하고 생성 시 주변 범위의 this값을 받는다.
this를 확인하려면, 화살표 함수가 생성된 윗줄로 이동하고, 그곳의 this값이 무엇인지 확인한다.
그 this 값이 화살표 함수 안의 this값과 같을 것이다.
const obj = {
value: 'abc',
createArrowFn: function() {
return () => consolelog(this);
}
};
const arrowFn = obj.createArrowFn();
arrowFn(); // { value: 'abc', createArrowFn: ƒ}
다시 규칙 3으로 돌아가서, 우리가 obj.createArrowFn()을 호출할 때, createArrowFn 안의 this는 점 표기법에 의해 obj가 될 것이다. 따라서 obj는 arrowFn에서 this로 바인딩된다. 만약 우리가 전역 범위에서 화살표 함수를 생성했다면, this는 window가 되었을 것이다.
규칙 적용해보기
코드 예제를 살펴보고, 우리의 규칙을 적용해보자.
두 가지 다른 함수 호출 예제에서 this가 무엇이 될지 알아내 보자!
1. 어떤 규칙이 적용되었는지 알아보기
var obj = {
value: 'hi',
printThis: function() {
console.log(this);
}
};
var print = obj.printThis;
obj.printThis(); // { value: 'hi', printThis: ƒ }
print(); // Window { stop: ƒ, open: ƒ, alert: ƒ, .... }
obj.printThis()는 규칙 3의 점 표기법을 사용한 호출에 해당한다.
print()는 규칙 4의 자유 함수 호출에 해당한다. pritn()에서는 new, bind / call / apply 또는 점 표기법이 사용되지 않았다.
그러므로 print()는 규칙 4에 해당되고 this는 전역 객체인 window가 된다.
2. 다양한 규칙이 적용되었을 때
다양한 규칙이 적용되어있을 때, 위에서 작성한 순서대로 먼저 적용되어야 한다.
var obj1 = {
value: 'hi',
print: function() {
console.log(this);
}
};
var obj2 = { value: 17 };
만약 규칙 2와 규칙 3이 같이 적용되어 있을 때, 규칙 2가 우선시 된다.
obj1.print.call(obj2); // { value: 17 }
만약 규칙 1과 규칙 3이 적용되어있다면 규칙 1이 우선시 된다.
new obj1.print(); // {}
라이브러리 내에서의 this
라이브러리들은 종종 함수 내에서 의도적으로 this값을 바인딩한다. this는 함수를 사용하기에 가장 유용한 값으로 바인딩된다.
jQuery를 예로 들자면, this를 해당 이벤트에 대한 콜백에서 이벤트를 트리거하는 DOM요소로 바인딩한다.
만약 라이브러리에서 규칙들을 따르지 않은 예기치 않은 this값들이 있다면, 해당 문서를 체크해보아야 한다.
해당 값은 위에서 설명한 것과 같이 bind를 사용하여 바인딩되고 있을 수 있다.
그동안 this가 무엇이냐 라고 했을 때 명확히 답변할 수 없었다.
이 글을 읽으면서 this는 호출되는 위치에 따라 다르며, 몇 가지 규칙에 의해 this가 무엇이 되는지 알게 되었다.
나중의 내가 다시 읽을 것을 대비해 미리 번역했는데 정말 만만치 않았다^^...
- 출처 : https://codeburst.io/the-simple-rules-to-this-in-javascript-35d97f31bde3
'Frontend > Javascript' 카테고리의 다른 글
[javascript] 웹 페이지에서 javascript가 하는 일 (0) | 2021.09.12 |
---|---|
[javascript] 동기 / 비동기 (1) | 2021.08.30 |
Javascript new (0) | 2021.08.25 |