4 분 소요

컴퓨터 구조 (Computer Architecture)

컴퓨터구조

명령어 구조 (Command Architecture)

명령어 구조

운영체제 (Operation System)

운영체제

컴파일러 (Complier)와 추상 구문 트리 (Abstract Syntax Tree)

프로그래밍 코드에서 프로그램으로

컴파일러와 AST

자바스크립트 (JS) : 브라우저에 동작하는 경량 프로그래밍 언어로 개발

  • 초창기에는 웹 서버로부터 전달받은 HTML/CSS를 단순히 렌더링하는 수준에 머무름
  • 1999년, 비동기로 데이터를 교환하는 Ajax 기능이 도입돼, 필요한 데이터만 받아 렌더링하는 것이 가능해짐
  • 2006년, DOM을 쉽게 제어할 수 있는 JQuery가 등장
  • 2008년, 구글의 크롬 V8 JS 엔진으로 웹 서버에서 수행되던 로직이 브라우저로 이동
  • 2009년, Node.js로 브라우저 이외의 환경에서도 JS 엔진을 동작시킬 수 있게 됨
    • 프런트엔드와 백엔드 모두에서 활용될 수 있는 동형성 (isomorphic)이 보장
    • 비동기 I/O를 지원하고 단일 스레드 이벤트 루프를 기반하여, 실시간 데이터 처리가 빈번한 SPA에 적합
      • SPA (Single Page Application) : React, Vue.js

기술 운영 위원회 (TC39)가 JS의 공식 명세를 관리하며, ECMA 표준 기구에 의해 공식화

  • ECMAScriptJS의 공식 명칭으로, 2016년 이후부터는 개정연도를 붙어 명세화
  • 0~5단계에 거친 TC39 프로세스를 통해 새로운 아이디어를 관리
  • TC39ECMA를 통해 관리되는 JS의 공식적인 표준 버전은 단 하나!
    • 브라우저, 디바이스 제조사는 해당 명세서를 기준으로 JS 구현체를 만듬
      • 오류 없이 웹 컨텐츠를 보여주기 위해, 에지 케이스를 다루는 기능을 자체적으로 추가하기도 함
      • 개정안을 반영할 때 기존에 잘 보이는 컨텐츠가 깨지는 불일치로 자사 엔진에 이를 반영하지 않기도 함
  • JS는 모든 브라우저에 내장된 브라우저 표준 프로그래밍 언어로 자리잡음
    • 개발자가 별도의 컴파일 작업을 수행하지 않는 인터프리터 언어 (Interpreter Language)
    • 모던 JS 엔진은 인터프리터와 컴파일러의 장점을 결합해, 비교적 속도가 느린 인터프리터의 단점 해결
    • 명령형 (imperative), 함수형 (functional), 프로토타입 기반 (prototype-based), 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어

프로그래밍 패러다임 : 코드를 어떻게 구조화할지에 대한 접근 방식과 사고 방식

  • 절차적 (procedural) : 코드를 톱다운, 선형적으로 구조화 (프로시저에 미리 정해진 연산 작성)
  • 객체 지향 (object-oriented) : 로직과 데이터가 정의된 클래스 기준으로 코드를 구조화
  • 함수형 (functional) : 코드를 부수 효과가 없는 순수 함수 단위로 구조화 (함수 자체가 값)
  • JS는 하위 호환성을 보장하지만, 상위 호환성을 보장하지 않음
    • 하위 호환성 (backwards compatibility) : 유효한 문법이라 인정되면, 이후에도 적용되어야 함
    • 상위 호환성 (forwards compatibility) : 나중에 추가되는 문법을 위한 입력이 처리 가능함

상위 호환성을 보장하지 않아 구 엔진과 호환되지 않는 문법은 트랜스파일 (transpile)을 통해 호환 가능

  • 바벨 (Babel) : 새로운 JS 문법을 오래된 문법으로 바꿔주는 트랜스파일러
    • 그냥 옛날 문법 쓰면 되는 거 아닌가? -> 개발자는 새로운 문법을 통해 클린한 코드를 짜는 데에 집중해야 함
    • 비교적 최근 추가된 문법으로 적은 예시 : let

    최근에 추가된 문법

    • 배포할 때에는 트랜스파일을 거친 산출물 배포 : let -> var로 변환하면서 별도 변수 정의

    바벨이 오래된 문법으로 변환

  • 상위 호환성 문제가 아직 지원하지 않는 API 메소드로 발생하였다면…?
    • 폴리필 (Polyfill) 패턴 : 해당 메소드가 오래된 환경에도 있었던 것처럼 하자!

JS는 컴파일 언어? 인터프리터 언어? 스크립트 언어??

  • 인터프리터 언어 (Interpreter Language) : 코드를 한 줄씩 읽어 해당 줄을 즉시 실행하는 프로그래밍 언어

    인터프리터, 스크립트 언어의 실행 절차

    • 런타임에 코드를 한 줄씩 해석해 실행 → 실행 단계에서 번역 (Interpretation at Runtime)
    • 변수의 타입을 런타임에 동적으로 결정 → 동적 타이핑 (Dynamic Typing)
    • 컴파일 언어에 비해 런타임은 비교적 느린 실행 속도를 갖고 있으나, 메모리를 비교적 작게 사용
  • JS는 인터프리터, 스크립트 언어로 분류되나, 파싱·컴파일 이후에 실행된다는 점에서 컴파일 언어의 요소 또한 존재

    파싱 컴파일 후 JS 실행

    1. 개발자가 작성된 코드는 바벨이 트랜스파일하고, 웹팩과 같은 번들러를 거쳐 번들링되어 JS 엔진에 전달
    2. JS 엔진은 전달받은 코드를 파상에 추상 구문 트리로 바꿈
    3. JS 엔진은 추상 구문 트리를 이진 바이트 트리로 바꿈
      • JIT 컴파일러가 실행된 시점에 필요한 부분을 동적으로 바로 컴파일
    4. JS 가상 머신이 프로그램을 실행

브라우저 (Browser) : 웹 페이지를 서버에게 응답받은 HTML, CSS, JS 파일로 표현

  • HTMLCSS는 브라우저 렌더링 엔진의 HTMLCSS 파서에 의해 DOMCSS Object Model 트리로 파싱
    • HTML 파서가 Script 태그를 만날 때, DOM 생성을 중단하고 JS 엔진에게 제어권을 넘김
    • Script 태그의 위치에 따라 DOM 생성이 지연되므로, DOM 영역 아래에 스크립트 태그를 삽입하는 것이 권장
  • Internal JS : HTML 태그의 속성 script=""JS 코드를 넣는 방법
<script>
  alert ("Hello");
</script>
  • Linking JS : 별도의 .js 파일을 만들고 이를 HTML 문서와 연결하는 방법
// hello.js
alert ("Hello");
// index.html
<script src="hello.js"></script>

브라우저 렌더링 (Browser Rendering)이 이루어지는 과정?

  1. Connect & Request to Server
  2. HTML/CSS Parsing → Token/Lexer → Node → DOM, CSSOM → Render(DOM/CSSOM) Tree
  3. JS Parsing ⇒ AST(ByteCode) → Run with Render Tree(DOM/CSSOM)
  4. Layout (Reflow ← Change Browser Size)
  5. Paint (Repaint ← Reflow)
  6. Composite

Node.js : 브라우저 밖에서 JS 코드를 실행하게 해주는 런타임 환경

  • 브라우저 내부가 아닌 외부에서 JS를 실행할 수 있는 환경 제공
    • 브라우저와 동일하게 JS의 코어인 ECMScript를 제공
    • 파싱된 HTML 요소를 선택 및 조작하는 DOM API이나 클라이언트 사이드 Web API를 제공되지 않음
    • 파일을 생성 및 수정할 수 있는 파일 시스템 및 Node.js 고유 API 제공

alert(), console(), … : 모든 웹 환경에서 지원하는 함수

  • 전역 스코프에 API를 추가해 자체적으로 사용 가능한 기능 제공
  • JS 함수와 객체 메소드 규칙을 따르고 표면상 JS 문법 규칙을 준수

개발자 도구 : 개발자의 편의를 위한 도구 (정의된 명세를 정확히 재현하는 도구 X)

  • JS의 프로그램 처리 방식을 항상 엄격하게 준수하지 않음! (순수 JS 작동 방식을 보장하지 않음)
  • 콘솔 ‘전역 스코프’ 최상위 레벨에서 var, function으로 변수, 함수를 선언하면 실제 전역에 변수가 생기는지?
  • 콘솔 ‘전역 스코프’ 최상위 레벨에서 let, const로 여러 변수를 선언했을 때의 작동 방식?
  • 첫번째 줄에 ‘use strict;‘를 입력하였을 대, 해당 콘솔 세션이 엄격 모드로 작동하는지?
  • 비엄격 모드에서 함수 호출 시, this 기본 바인딩 방식?
  • ‘전역 객체’가 쓰일 때, 실제 기대하는 전역 변수가 이 전역 객체 있는지?
  • 여러 줄을 입력할 때에서 호이스팅의 작동 방식?

태그:

업데이트: