함수 실행(call) 시 로컬 메모리와 로컬 실행 컨텍스트(execution context)가 생성된다.
단, execution context(a.k.a 메모리 테이블)은 함수 단위의 스코프에 생긴다(블록 단위가 아님)
execution context의 call stack에 담기는 것들
-scope 내 변수 및 함수(Local & Global)
-전달 인자(arguments)
-호출된 근원(caller) =어디서 불렀는지임 ex)해당 함수를 호출하는 함수
-this
this?
(보통 exectution context와 this를 구분하지 않지만 엄밀히는 아래와 같음)
- 모든 함수 scope 내에서 자동으로 설정되는 특수한 식별자
- execution context의 구성 요소 중 하나로, 함수가 실행되는 동안 이용 가능함
내가 생각하기에 this는 모듈을 만들기 위해서 만들어진게 아닌가 싶다. this를 이용해 함수를 작성하면 함수가 실행되는 환경을 특정하지 않아도 실행되는 함수를 만들 수 있기 때문이다.
1. 전역에서 this는 window이다.
2. 함수를 실행했을 때(function invocation) 함수 안의 this는 window이다.(아래 3번과 마찬가지 방식으로 부모가 window이므로)
*함수 안에 함수가 겹쳐진 안에 this가 있더라도 마찬가지
----------------------------
**1, 2번의 경우 흔히 사용되는 방법이 아니다! 호출시 바인딩되는 객체가 브라우저인지 node.js인지, strict mode인지 아닌지에 따라 다양하게 달라지기 때문! 그냥 알아만 두자!
----------------------------
3. Method 호출 시 this는 실행되는 시점에서 한 단계 위의 직계 부모 object(실행 시점의 온점 왼쪽의 객체)를 의미한다!
4. construction mode( new 연산자로 생성된 function 영역의 this) 즉, 새로 생성된 객체를 의미한다.
(다른 언어에서 this는 보통 4번 방식으로만 쓰인다.)
5. .call 이나 .apply 호출 시 this는 call이나 apply의 첫 번째 인자로 전달된(명시된) 객체를 의미한다.
let add = function(x, y) {
this.val = x + y;
}
let obj = {val: 0}
add.call(obj, 2, 8); // 이 경우, 첫 번째 인자인 obj가 this가 된다.
console.log(obj.val); //10
add.apply(obj, [2, 8]); // 이 경우, 첫 번째 인자인 obj가 this가 된다.
console.log(obj.val); //10
.call과 .appy의 차이 = .call은 리스트(쉼표)로 넘겨주고, .apply는 배열로 넘겨준다
//.call의 예제 1
'피, 땀, 눈물'.split(',') = [피, 땀, 눈물];
''.split.call('피, 땀, 눈물', ',') = [피, 땀, 눈물];
//.call의 예제 2
let allDivs = document.querySelectorAll('div'); // querySelectorAll의 결과는 NodeList라는 유사 배열
[].map.call(allDivs, function(el) {// allDivs를 this로 지정
return el.className
})
// allDivs는 유사 배열이므로 map 메소드가 존재하지 않음.
// 그러나, Array prototype으로부터 map 메소드를 빌려와 this를 넘겨 map을 실행이 가능해진다.
.call의 예제
***.call과 .apply의 의의는?
->this 값을 특정할 때 사용하며, 특히 apply의 경우 배열의 요소들을 풀어서 인자로 넘길 때 유용함.
Math.max(2, 3, 5, 1, 10, 14); // 14
하지만 배열의 인자들에 Math.max를 사용하려면?
let arr = [10, 3, 5, 7, 1, 23];
Math.max.apply(null, arr) //this는 없고 배열 arr의 요소를 풀어주었다.(Math는 생성자가 아니라 this가 필요 없음)
이런 식으로 사용!
하지만 spread operator가 도입된 이후로는 굳이 .apply를 쓸 필요 없이
Math.max(...arr)
면 충분하게 되었다.
'JavaScript' 카테고리의 다른 글
...args와 arguments의 차이 - JavaScript (0) | 2020.09.29 |
---|---|
동기(synchronously) 비동기(asynchronously) 호출 - JavaScript (0) | 2020.09.29 |
callback 함수에 ()를 달지 않는 이유 (0) | 2020.09.25 |
.match() 메소드 - JavaScript (0) | 2020.09.23 |
.indexOf() 메소드 - JavaScript (0) | 2020.09.23 |