인간 JS 엔진되기 1

제로초님의 인간 js 엔진되기를 보고 정리한 게시글이다.

1
2
3
4
5
6
7
8
9
10
const add = (a, b) => a + b;

function calculator(func, a, b) {
return func(a, b);
}

add(3, 5); //8
calculator(add, 3, 5); //8

document.querySelector("#header").addEventListener("click", add);

함수 호출과 함수의 실행

호출은 함수의 결과값으로 대체해서 생각하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import {useCallback}from 'react';

export const App=()=>{
const onClick=useCallback((e)=>{
console.log(e.target);
},[])

return (
<div onClick={onClick()}></div>
// 즉시 실행되어서 e is undefined 에러가 발생한다.
<div onClick={onClick}></div>
// <div onClick={(e)=>{console.log(e.target)}></div>
}
)
}

호출스택

함수의 호출은 스택에 하나의 노드를 삽입한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const x = "x";

function c() {
const y = "y";
console.log("c");
debugger; // call Stack을 확인할 수 있다.
}

function a() {
const x = "x";
consoe.log("a");
function b() {
const z = "z";
console.log("b");
c();
}
b();
}

a(); // 익명함수 a b c
c(); // 익명함수 c

// a b c c

스코프체인

js에서 scope는 변수에 접근할 수 있는 범위이다.

함수객체로부터 시작해서 상위 실행컨텍스트를 연결리스트 형식으로 관리한다.

변수나 선언에 접근할 때 해당 함수 객체의 실행컨텍스트를 탐색하고 없을 경우 연결리스트의 다음 노드의 실행컨텍스트를 검색한다. 이를 스코프체인이라고 한다.

호이스팅

const나 let 선언보다 위에서 변수에 접근을 했을 경우 해당 영역을 TDZ(temporal dead zone)라고 부른다.

실행컨텍스트를 구성하면서 인터프리터가 변수 내의 메모리공간을 미리 할당해놓기 때문에 발생하는 현상이다.

var의 경우 호이스팅하면서 undefined로 초기화하지만 let과 const는 호이스팅시에 변수를 초기화하지 않는다.

funcion의 경우 선언과 내용 둘 다 호이스팅된다.

this

nodejs와 js에서 this는 기본적으로 globalThis를 가리킨다.

아래의 네 경우가 아닐 경우에 this는 globalThis라고 봐도 무방하다.

  1. this는 함수가 호출될 때 정해진다.
1
2
3
4
5
6
7
8
9
10
11
12
const obj = {
name: "박성현",
sayName() {
console.log(this.name);
},
};

obj.sayName(); // 박성현

const sayN = obj.sayName;

sayN(); // '' (window.name)

##2. 화살표 함수의 this는 무조건 상위 실행컨텍스트의 this를 가리킨다.

1
2
3
4
5
6
7
8
const obj = {
name: "박성현",
sayName: () => {
console.log(this.name);
},
};

obj.sayName(); // '' (window.name)
  1. new로 객체를 만들게 되면 this는 인스턴스를 가리킨다.
1
2
3
4
5
6
7
function Human(name) {
this.name = name;
}

new Human("박성현");

//Human(name:'박성현')
  1. call,bind,apply로 this를 명시적으로 바인딩 할 수도 있다.
    다만 화살표함수는 바인딩할 수 없다.
1
2
3
4
5
6
function sayName() {
console.log(this.name);
}
sayName.bind({ name: "박성현" })(); //박성현
sayName.apply({ name: "박성현" }); //박성현
sayName.call({ name: "박성현" }); //박성현

스코프와 매개변수

변수에 접근할 때 스코프체인을 순회하며 탐색한다.

실행컨텍스트는 매개변수를 포함하여 생성된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const x = true;
const y = false;

function a(){
let a=4;
if(x){
let a=3;
for(let i=0;i<a;i++>){
console.log(i);
}
if(y){
kkk();
}
}
// z(); error
}

a();
const z=()=>{};

댓글