Node.js 교과서 : 2. 알아두어야 할 자바스크립트

전지연·2025년 10월 7일

GDGoC_2025

목록 보기
2/16
post-thumbnail

호출 스택

  • first, second, third 함수가 차례대로 서로를 호출할 때, first, second, third 함수가 차례대로 쌓이는 것
  • 동기적으로 실행되는 것을 파악할 때 사용(동기 : 순서대로)

이벤트 루프 알아보기

setTimeout

: 비동기 코드 중 하나, 시간 지연 기능

콘솔에 출력되는 순서 : '시작' -> '끝' -> '3초 후 실행'

이는 호출 스택만으로 설명할 수 없음
=> 이벤트 루프 사용


이벤트 루프

자바스크립트 브라우저의 내부 요소
: 호출 스택, 백그라운드, 태스크 큐, 콘솔창, 메모리

이벤트 루프의 역할
: 호출 스택이 비어 있을때 태스크 큐에서 함수들 하나하나를 호출 스택에 끌어와서 실행한다.

예제1 코드의 실행 과정

  1. 호출 스택에 anonymous 함수 추가
  2. 호출 스택에 console.log 함수 추가
  3. console.log pop
  4. 호출 스택에 setTimeout 함수 추가(setTimeout은 비동기 함수)
  5. 백그라운드에 타이머(run, 3초) 전송
  6. 호출 스택에 console.log(끝) 추가
  7. console.log(끝) pop
  8. anonymous pop
  9. 타이머 3초가 다 끝나면 run을 태스크 큐로 전송
  10. 이벤트 루프 - 태스크 큐에 있는 run을 호출 스택으로 끌고 옴

예제2 코드의 실행 과정

  1. 호출 스택에 anonymous 함수 추가
  2. 호출 스택에 setTimeout(run, 5000) 함수 추가
  3. setTimeout pop
  4. 백그라운드에 타이머(run, 5초) 전송
  5. 5초 후 run함수를 태스크 큐로 전송
  6. 이벤트 루프 - 비어 있는 호출 스택에 태스크 큐에 있는 run을 전송
  7. run 실행 -> 콘솔 창에 run run작성
  8. 호출 스택의 run 위에 setTimeout(익명, 0) 함수 추가
  9. setTimeout pop
  10. 백그라운드에 타이머(익명, 0초) 전송
  11. new Promise 실행 - 호출 스택에 new Promise 실행
  12. Promise는 내부까지 동기 - 호출 스택에 resolve('hi') 함수 추가
  13. resolve, Promise 차례로 pop
  14. then으로 인해 Promise는 비동기로 동작 - 백그라운드에 then console.log(hi) 전송
  15. 호출 스택에 oneMore 추가
  16. oneMore 실행되면서 호출 스택에 console.log 추가
  17. console. oneMore, run 차례로 pop
  18. 백그라운드에 남아있는 타이머는 바로 실행 - 태스크 큐에 '익명'전송
  19. 백그라운드에 남아있던 console.log('hi')도 태스크 큐로 전송
  20. 이때 Promise가 우선순위가 높음 - 호출 스택에 console.log('hi') 전송(이벤트 루프 동작)
  21. 콘솔창에 hi 출력
  22. 익명 함수도 호출 스택으로 이동하여 실행됨(이벤트 루프 동작) - 콘솔창에 wow 작성

var, const, let

var

  • ES2015 이전에는 var로 변수를 선언(이후는 const, let으로 선언)
  • var은 {} 바깥에서도 호출 가능, const는 {} 바깥에서 호출 불가능
if(--) {
	var x = 3;
}
console.log(x); //3
if(--) {
	const x = 3;
}
console.log(x); // 호출안됨
  • function 중괄호는 var도 통과할 수 없음

const와 let의 차이점

  • const 는 변수 변형 불가
const a = 3;
a = 5;    //에러
const c;  //에러
  • but 객체는 변형 가능
const b = {name: 'zero'}
b.name = 'nero' // 가능
  • let은 변수 변경 가능
let a = 3;
a = 5;    //가능

템플릿 문자열, 객체 리터럴

템플릿 문자열

: 변수를 $와 {}로 호출하는 것

var won = 1000;
const ex = won +const result = ${won}

ex와 result는 똑같이 출력됨

객체 리터릴

  • 속성명, 변수명이 동일한 경우 한 번만 작성
//이전
name: name

//이후
name
  • [변수 + 값] 으로 동적 속성명을 객체 속성 명으로 사용 가능
// 속성명 : ES6
// 선언
[es + 6]

화살표 함수

function add1(x, y) {
	return x + y;
}

const add2 = (x, y) => {
	return x + y;
}

const add3 = (x, y) => x + y;

const add4 = (x, y) => (x + y);

add 1, 2, 3, 4 모두 같은 함수이다.

function not1(x) {
	return !x;
}

const not2 = x => !x;

not 1, 2는 같은 함수이다.

this

기존 function과 다른 점은 this 방식이다.

  • 화살표 함수는 부모 함수의 this를 물려받음
  • 기존 function은 부모 함수와 자식 함수의 this가 다름
    => 이로 인해 부모 함수와 자식 함수의 this를 같게 만들려면 that을 사용해야 함

구조분해 할당

const example = {a: 123, b: {c: 135, d: 146} }

// 기존
const a = example.a;
const d = example.b.d;

// new
const { a, b: { d } } = example;

이런 식으로 코드를 작성하면 a = 123, d = 146 이런 식으로 선언이 된다.

arr = [1, 2, 3, 4, 5]

// 기존
const x = arr[0]
const y = arr[1]

// new
const [x, y, , , z] = arr;

이 역시도 x, y를 각각 선언하지 않고 arr의 값을 꺼내와서 x, y, z를 선언할 수 있다.

this는 함수를 호출할 때 어떻게 호출되었냐에 따라 결정되기 때문에 this를 사용한 경우에는 구조분해 할당이 문제가 될 수 있다.


클래스

기존에는 생성자 따로, static 메서드 따로, instance 메서드 따로 선언해야 했음

기존 코드

이후에는 클래스 안에 전부 함께 선언할 수 있음

클래스 코드


Promise, async/await

Promise

: 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체

  • then을 붙이기 전까지는 promise가 결과값을 가지고 있다가, then을 붙이면 결과를 반환
  • resolve(성공리턴값) -> then으로 연결
  • reject(실패리턴값) -> catch로 연결
  • finally는 무조건 실행

Promise.all

Promise.all(배열) : 여러 개의 프로미스를 동시에 실행

  • 하나라도 실패하면 catch로 연결
  • allSettled로 실패한 것만 추려낼 수 있음(all은 안쓰는 추세)

await

  • 코드 내에 있는 then을 한번 더 축약

이 코드에서

then((user) => {

가 반복되는 것을 변수로 저장한다. 실행 순서는 await이 먼저이다.

let user = await Users.findOne({});
  • let user = await Users.findOne({});
    이 코드에서 Users.findOne(..)이 Promise, await은 then역할을 한다.
  • user = await user.save();
    이 코드에서 user.save()가 Promise, await이 then역할을 한다.
  • user = await Users.findOne(..)이 Promise, await이 then역할을 한다.

async

이전에는 await을 위해서는 async function안에 작성해야 했다.

이후에는 async 없이도 await을 사용할 수 있다.

for await(변수 of Promise 배열)

(async () => {
	for await(promise of [promise1, promise2]) {
    	console.log(promise);
    }
})();

for await : promise를 반복할 때 사용


Map, Set, WeakMap, WeakSet

Map

  • Map은 객체와 유사, Set은 배열과 유사
  • Map은 { 키, 값 } 으로 set할 수 있다.
const m = new Map();

m.set('a', 'b');
m.set(c, 'd');   // 키 값은 객체도 가능
  • 키와 값은 객체도 가능하다.
m.set({a : 'b'}, {c: 'd'});
  • 다만 이 경우에는 키로 값을 가져올 수 없다.
m.get({a : 'b'})    // undefined
// m에 set되어 있는 {a : 'b'}와 새로 입력한 {a : 'b'}는 참조값이 다름
  • 이 경우에는 {a : 'b'}를 선언 후 set해야 한다.
const obj = {key, 'key'}
m.set(obj, 123)
m.get(obj) // 이 경우에는 값이 나옴
  • size : map의 크기 측정(length 사용 불가)
  • for 반복문
for (const [k, v] of m) {
	console.log(k, v);
}
  • forEach도 사용 가능
m.forEach(v, k) => {
	console.log(k, v);
});
  • has : Map안에 원하는 값이 들어 있는지
m.has(obj)
  • delete : 지우기
m.delete(obj)
  • clear : 다 지우기
m.clear

Set

  • 중복을 허용하지 않는 배열
    (다만 자료형이 다르면 가능하다)

  • set은 Map과 다르게 add를 사용(map은 set사용)

const s = new Set();
s.add(1);
  • size, has, forEach, delete, clear는 Map과 동일하게 사용
  • for 반복문
for (const a of s) {
	console.log(a);
{

WeakMap, WeakSet

const wm = new Map();
let obj4 = {};
wm.set(obj4, '123')
obj4 = null;   // 안사라짐

이 경우에는 garbage collecting이 자동으로 되지 않는다.

Garbage Collection
쓸모 없어진 객체가 차지하는 메모리를 자동으로 해제하는 것

weakMap은 garbage collecting이 자동으로 된다.

const wm = new WeakMap();
let obj4 = {};
wm.set(obj4, '123')
obj4 = null;   // 사라짐

널 병합, 옵셔널 체이닝

  • 널 병합 연산자 : ??
  • 옵셔널 체이닝 연산자 : ?.

널 병합 연산자(??)

: 왼쪽 값이 null과 undefined 일때만 오른쪽 값을 반환

const a = 0;
const b = a || 3;   // ||는 모든 falsy 값일 때 오른쪽 값을 반환

const c = null;
const d = c ?? 3;   //c가 null이기 때문에 d에는 3이 대입됨
console.log(d);   // 3

옵셔널 체이닝(?.)

: null과 undefined를 조회할 때 에러 발생하지 않도록 막음

const c = null;
c.d    //에러
c?.d   //문제없음

함수도 다음과 같이 호출할 수 있다.

c?.f()
const A = {'a', 'b', 'c'}
A?.[0]

프론트엔드 자바스크립트

AJAX

: 서버로 요청을 보내는 코드

  • get 요청 보내기
then과 catch 사용해서 전송await 사용해서 전송
  • Post 요청 보내기
    get 요청 전송과 비슷하지만 두 번째 인수로 데이터를 넣어 보냄

FormData

: formData 객체를 만들어서 요청에 첨부

encodeURIComponent, decodeURIComponent

주소창에 한글 입력할 때 decodeURIComponent로 감싸서 입력

https://~~/${encodeURIComponent('노드')

data attribute와 dataset

  • HTML 태그에 데이터를 저장
  • 태그 속성으로 data-속성명
  • 자바스크립트에서 태그.dataset.속성명으로 접근 가능
    ex. HTML : data-id // 자바스크립트 : dataset.id

0개의 댓글