Javascript

[Javascript] JS 기술 파헤치기🥄 (1)

jelly._.me 2025. 4. 19. 14:39

 

 

나혼자 공부하고 복습 정리하는거라 가독성 0임..

 

💯 1. 클로저

클로저 : 함수 내부에 있는 지역변수의 상태값을 기억하는 거! 함수는 한 번 호출되면 실행 컨텍스트라는 특별한 환경을 만듭니다. 그 안에 지역 변수도 있고요. 그런데 클로저는 이 실행 컨텍스트가 끝난 후에도, 그 안에 있는 변수들을 기억할 수 있게 함! 외부에선 직접 접근이 불가함

⇒ 안전한 상태관리! 코드의 안정화 (전역변수는 누구나 접근,바꾸게 되는데 얘는 캡슐화 되어서 불가함)

function makeCounter() {
  let count = 0; // 'count'는 makeCounter() 함수 내부의 지역변수

  return function() {
    count++; // 반환된 함수가 count에 접근해서 값을 변경
    return count; // 변경된 count 값을 반환
  };
}

const counter = makeCounter(); // makeCounter() 함수 실행
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

 

 

💯 2. 이벤트위임

그냥 일일이 하나의 요소에 이벤트 주는 방식은 → 반복문 써야함

WHY? NodeList 자체는 배열이 아니기 때문에 **addEventListener**를 바로 사용할 수 없다는 점!

const listItems = document.querySelectorAll('ul li');
listItems.forEach(item => {
  item.addEventListener('click', function() {
    alert('클릭된 항목: ' + item.textContent);
  });
});

 

하지만? 부모요소에 이벤트 달고, 이벤트 위임을 시키면 불필요한 메모리 사용도 줄이고, 동적 이벤트 위임도 가능함!

부모 자체에 이벤트 핸들러 달고, 인식 있으면 그 자식이 뭐였는 지에 따라서 분기처리!

(부모 컨테이너에 달고, 어디에서 이벤트 타깃이 되었는지 찾아 들어가면 됨)

const todoList = document.getElementById('todo-list');

todoList.addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') {
    alert('클릭된 항목: ' + event.target.textContent);
  }
});

 

장점
1. 동적 요소 처리: 이벤트 위임을 사용하면 동적으로 추가된 자식 요소들도 처리 ㄱㄴ.
2. 성능과 메모리 효율: 부모 요소에 하나의 이벤트 리스너만 추가하므로 성능상 더 유리하고, 메모리 사용을 줄

 

 

 

💯 3. 프로토타입 상속 (Feat. 프로토타입 체인)

// 부모 객체
const parent = {
  name: '부모',
  greet: function() {
    console.log('안녕하세요, ' + this.name);
  }
};

// 자식 객체
const child = Object.create(parent);  // child는 parent의 프로토타입을 상속받음

child.name = '자식';  // 자식 객체에 name 속성 추가

// 부모 객체의 greet 메서드를 호출
child.greet();  // "안녕하세요, 자식"

=> 프로토타입 체인?

  • child는 parent의 프로토타입을 참조.
  • parent는 Object.prototype의 프로토타입을 참조.
  • Object.prototype의 프로토타입은 null이어서 여기서 끝.

객체가 특정 속성(예: name)을 가지고 있지 않으면, 자바스크립트는 그 객체의 프로토타입(부모 객체)을 찾아서 그 안에 해당 속성이 있는지 확인해요. 만약 부모 객체에도 없으면, 그 부모의 프로토타입을 찾아서 계속 검색해요. 이 과정이 프로토타입 체인

없으면 → null로 반환함

 

 

💯 4. 호이스팅

선언문이 코드의 선두로 끌어올려진 것처럼 동작하는 자바스크립트의 고유한 특징

  • 함수 선언문 var이로 인해 함수를 선언하기 전에 호출하더라도 에러가 발생x
  • 함수 전체가 호이스팅되어 코드의 맨위로 끌어올려진것처럼 동작
  • 변수 선언문 let, const따라서 변수를 선언하기 전에 접근하면 최종적으로 undefined가 반환됨 !
  • 변수의 선언만 호이스팅되며 변수의 초기화는 호이스팅되지 않음
Q. 왜 let과 const는 undefined가 아니라 ReferenceError일까?

let과 const는 변수를 선언하기 전까지 해당 변수를 사용할 수 없는 상태임.
undefined가 반환되지 않고 변수 자체가 "존재하지 않음" 상태이므로 ReferenceError가 발생!

반면, var는 선언만 호이스팅되기 때문에 초기화 전에 변수에 접근하면 undefined를 반환

 

 

💯 5. 이벤트 버블링

이벤트가 발생 시 해당 요소에서 이벤트가 처리 된 후 상위 요소로 이벤트가 전파되는 현상

⇒ 그래서 이벤트 위임을 쓸 수 있게 되는거임!!

이벤트 버블링을 통해 이벤트가 전파되는 동안 부모 요소에서도 그 이벤트를 감지할 수 있게됨

따라서 이벤트를 처리하는 핸들러 함수를 부모 요소에 등록하면, 자식 요소에 발생한 이벤트를 모두 처리할 수 있으며, 이를 통해 여러 개의 하위 요소에 발생하는 이벤트를 하나의 이벤트 핸들러로 바인딩하는 이벤트 위임 처리 ㄱㄴ해짐

 

💯 6. 이벤트 캡처링

이벤트 버블링과 반대로, 상단에서 하단 방향으로 이벤트가 전파됨

잘 안 쓰긴 하지만,, 이렇게 구현함 (핸들러의 3번째 인자에서!)

divs.forEach((div) => {
  div.addEventListener("click", clickEvent, { capture: true });
});

 

💯 7. same-origin policy

Same-Origin Policy 동일 출처 정책과 CORS 에러

프로토콜, 호스트, 포트가 동일한 서버로만 ajax요청을 받도록 함! → 보안 측면에서의 정책 (공격 받을 경로를 줄이는 겨)

BUT, 이 제한을 좀 더 열어주고 특정 포트나 도메인 열어서 허용하는 방법이 CORS임!

 

 

💯 8. 동기 비동기 함수

동기, 비동기란? (+Promise, async/await 개념)

  • 동기 함수 : 순서대로, 앞의 실행이 끝날 때까지 기다림[요청 - 응답] 요 이후에 그다음 태스크 진행됨
  • 물론, cpu사용은 동일하더라도, 조금은 비효율적임
  • 비동기 함수 : 기다리지 않고 해당 태스크를 처리할 수 있음ex) 프로미스, .then(), async/await
  • 대신, 비동기 작동 이후에 반드시 프로미스를 반환!

 

💯 9. 이벤트 루프

이벤트 루프 == 비동기 함수들을 적절한 타이밍에 작동시키는 관리자!

이벤트 루프는 콜스택에 현재 실행 중인 컨텍스트가 있는지 또한 태스크 큐에 대기중인 함수등이 있는지 반복해서 확인하는 역할

  • 여기서 만약 콜스택이 비어있고, 태스크 큐에 대기중인 함수가 존재하면 이벤트 루프는 순차적으로 태스크 큐에 대기중인 함수를 콜스택으로 이동
  • 이후 콜스택으로 이동한 함수는 실행되고, 최종적으로 태스크 큐에서 일시 보관된 함수는 비동기 처리방식으로 동작

언어 자체의 설계를 바꾸는 것 보단, 브라우저의 멀티 스레드를 이용하는 자바스크립트의 비동기 프로그래밍을 지원하는 것. 그리고 이 비동기 프로그래밍의 핵심이 이벤트 루프인 겨!

여기 링크 내에 있는 움짤 보면서 이해하길

 

 

 

💯 10. 스택과 큐

  • 콜 스택: 동기처리, 일반적으로 함수의 실행 순서를 추적하는 구조로 함수 호출 시 스택에 추가하고 실행이 완료되면 콜스택에서 제거
  • 테스크 큐: 비동기 함수의 콜백함수 혹은 이벤트 핸들러등을 일시적으로 보관하는 영역, 비동기 함수가 호출되면 해당 함수의 콜백함수가 태스크 큐에 추가
  • 이후 이벤트 루프가 콜스택이 비어있는지 확인하고, 콜스택이 비어있을 경우에만 태스크 큐에서 콜백함수 가져와 콜스택에 추가하고 함수를 실행**(=틱)**

[JS] 자바스크립트 동작 원리(콜 스택, 콜백 큐, 이벤트 루프)