오늘은 어제의 작은 궁금증이 나비효과처럼 커졌던 날이다.
220607 TIL 에서 마지막 쯤에 find 메소드에 대해서 MDN을 찾아 보았다. 거기서 thisArg 매개변수가 있었고, 해당 내용에 대해서 몰랐기에, 오늘 찾아 보기로 했다.
MDN 에서는 '선택 항목. 콜백이 호출될 때 this
로 사용할 객체' 로 나와 있었다. 현재까지 알고있는 this
는 클래스를 생성하고 constructor를 이용하여 가져오는 this였다. 이 또한 정확히 아는 개념이 아니기도 하다.
한 블로그에 가보니 먼저 Execution Context에 대해서 설명하였다. 갑작스럽게 많은 정보의 양의 다소 괴로웠다. 실행 컨텍스트라고 하고, 자바스크립트의 코드가 실행하기 위해 음.. 메모리 할당?의 과정이라고 이해했다. 실행 컨텍스트가 let, const, var과 같은 변수 선언 방식이나, scope, hoisting같은 개념을 다 거치기 때문에 미리 숙지해야 할 것들도 많았다.
Scope?
Hoisting?
let, const, var?
다행히도 이전 포스팅으로 어느정도 개념을 알고 들어갔다고 생각했다. 무엇 먼저 이해해야 하는지 헷갈린다 ㅠ. Execution Context의 종류는 3가지라고 한다.
javascript 엔진에는 context를 관리하는 목적으로 Call Stack(호출스택)을 갖고 있다고 한다. js는 단일 스레드 형식이기 때문에 런타임에 단 하나의 Call stack을 갖고 있는다고 한다. 코드가 실행 되면 Call Stack 으로 Global Execution Context 를 생성하고 그위에 함수 순서대로 Functional Execution Context를 쌓는 식이라고 한다. 그리고 해당 Functional Execution Context가 끝나면 삭제하는 식으로 이루어진다고 한다. 해당 Stack에는 사이즈가 있어서 최대치를 넘을 경우 'RangeError' 가 뜬다고 한다. 이걸 Stack Overflow라고 한다.
Execution Context에는 두 가지 구성으로 이루어져 있다고 한다.
Global Execution Context's Lexical Environment에서 Reference to the outer environment 의 초기값은 null 이라고 한다.
여기서 임의의 function이 실행 된다면 먼저 Functional Execution Context's Lexical Environment를 확인한다고 한다. 다음 변수가 없다면 Functional Execution Context's Lexical Environment에 있는 Reference to the outer environment 를 참조 한다고 하는데 다음 가르키는 곳은 Global Lexical Environment라고 한다.
여기서 조금 이해가 안가는데 Lexical Environment안에 두 개의 속성이 있다고 생각했는데 우선 Lexical Environment를 먼저 확인한다고 하니 헷갈린다.
Environment Record는 Lexical Environment내에 식별자 바인딩을 기록하는 객체라고 한다.
Environment Record에는 세 가지 서브 클래스가 있다고 한다고 한다.
this
, super
등의 식별자 바인딩이 저장된다고 한다.Variable Environment
var로 선언된 변수가 메모리에 매핑되고, 초기값으로 undefined가 할당된다고 한다. 이건 Hoisting 개념에서 익혔던 것이다.
Lexical Environment
let, const로 선언된 변수가 매핑 된다고 하지만, 초기값은 할당 되지 않는다고 한다.
여기서 Variable Environment는 Lexical Environment를 상속하는 관계라고 한다. 그래서 둘 다 Lexical Environment라고 말할 수 있다고 한다. 그렇지만 Lexical Environment는 let과 const로 선언된 변수들로 local lexical Scope를 갖으며, Variable environment는 var로 선언된 변수들이 functional scope를 갖는다고 한다. 앞에서 얘기 했던 Environmet들의 속성을 조금 더 추가하여 설명하자면, Lexical Environment에서 Environment Record에서 참조값이 없으면 Reference to the Outer Environmet를 Variable Environment로 참조 한다는 것이다. Variable Environmet에 없으면? 다음은 Global로 outer Environmet로 이어진다고 한다.
this
는 어디에 있는가맨 앞에서 thisArg에서 출발한 의문점이 여기까지 왔다. 메소드에서 thisArg에 사용목적을 설명하라면 아직도 답하지 못 할 것이다. 하지만 적어도 this
에 대해서는 여기서 정리해 보자.
this
는 Lexical scope가 아닌 Global Scope를 참조 하고 있다고 한다. 그리고 아래와 같은 과정을 통해서 this
값을 결정한다고 한다.
strict mode
에서 정의된 함수일 경우, this
는 thisArg가 된다. this
는 global Object가 된다.this
는 toObject(thisArg)가 된다.위 과정을 거치고도 this
값이 정해지지 않는다면, this
는 thisArg가 된다고 한다.
call, apply, bind 모두 thisArg수정 함으로써 this
값을 바인딩 하는 것이라고 한다. 그리고 함수 호출 과정의 6번 단계와 관계가 있다고 하는데... 이해가 와닿지 않는 부분이다.
new
키워드와 함께 함수를 호출하면, this
는 아예 새로운 객체가 된다고 한다.인스턴스
화 될 때 this값은 인스턴스화 된 객체를 참조한다.function Aaa(x) {
console.log(this);
this.x = x;
console.log(this);
}
const aaa = new Aaa(20);
// Aaa {}
// Aaa {x: 20}
apply
, call
, bind
가 함수의 호출/생성에 사용되면, this
는 인수로 전달된 객체가 된다.
obj.method()와 같이 함수를 호출 하면 this는 obj가 된다.
자유 함수로 호출 되면, this
는 전역 객체(브라우저에서는 window
)가 된다.
단, strict mode
에서는 undefined가 된다.
위의 4가지 규칙 중, 다수가 적용되면 상위 규칙이 승리한다고 한다.
ES6에 새로 정의된 화살표 함수인 경우, 위의 규칙을 무시하고 Lexical Scope를 따라 상위 소코프의 this
값을 받는다고 한다.
여기서 2, 3, 5, 6이 이해가 안갔다 ㅠ. 6번 경우 new를 사용하지 않으면 1번 값과 거진 동일하게 출력하는 것을 알 수 있었다.. 차이점은 ...
const Aaa = (x) => {
console.log(this);
this.x = x;
console.log(this);
};
const aaa = new Aaa(20);
// TypeError: Aaa is not a constructor
const Aaa = (x) => {
console.log(this);
this.x = x;
console.log(this);
};
const aaa = Aaa(20);
// {}
// { x: 20 }
두서 없이 적어 내려갔다. 두서 없이 적어 내려간거 치고는 너무 오래 걸렸다 ㅠ. 그래도 조금은 조금은 이해를 했다. 이렇게 글쓰는게 어려울 뿐이지 ㅠ. 다음에 이어서 쓰기를 목표로 하면서 TIL를 마무리 한다.
[[JavaScript] 자바스크립트 this 키워드의 모든것, 코드 보관함, 2022년06월08일 접속]
https://muckycode.blogspot.com/2015/04/javascript-this.html
[[JavaScript] 자바스크립트 this란?,velog , 2022년06월09일 접속]
https://velog.io/@arski/JavaScript-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-this%EB%9E%80
[[JavaScript] 실행 영역(Execution Context)과 스코프(Scope), 코드 보관함, 2022년06월08일 접속]
https://muckycode.blogspot.com/2015/03/javascript-execution-context-scope.html
[JavaScript - Execute context,생활코딩 YouTube, 2022년06월08일 접속]
https://www.youtube.com/watch?v=QtOF0uMBy7k
[[JavaScript] Execution Context(실행 컨텍스트) 정의와 종류,가장 쉬운 웹개발 with Boaz YouTube, 2022년06월08일 접속]
https://www.youtube.com/watch?v=AbNc8_poxu4
[[10분 테코톡] 💙 하루의 실행 컨텍스트,우아한Tech YouTube, 2022년06월09일 접속]
https://www.youtube.com/watch?v=EWfujNzSUmw
[Execution Context(실행 컨텍스트)란?,velog , 2022년06월08일 접속]
https://velog.io/@stampid/Execution-Context%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80
[Context (실행 컨텍스트) 와 Hoisting (호이스팅), velog , 2022년06월08일 접속]
https://velog.io/@imacoolgirlyo/JS-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-Hoisting-The-Execution-Context-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-6bjsmmlmgy
[[JS]Execution Context와 Call Stack, Github, 2022년06월08일 접속]
https://dkje.github.io/2020/08/30/ExecutionContext/