Skip to content

Latest commit

 

History

History
171 lines (151 loc) · 9.11 KB

File metadata and controls

171 lines (151 loc) · 9.11 KB

0. 자바스크립트 엔진

  • JS를 실행하는 프로그램 or 인터프리터 언어

  • 엔진에 의한 인터프러터 방식으로 별도의 컴파일 과정이 필요없음.

    인터프리터 언어란 자바스크립트의 경우 코드 한 줄씩 입력해도 바로 실행(런타임)하여 결과 확인이 가능 자바스크립트란 웹문서 구조를 동적으로 나타내기 위한 언어

    컴파일러 언어란 특정 프로그래밍 언어로 쓰여있는 문서를 다른 프로그래밍 언어로 옮기는 언어 번역 프로그램 자바스크립트의 경우 고급 프로그래밍 언어를 기계어라는 다른 프로그래밍 언어로 번역하는 역할 수행

브라우저 별 엔진 종류

  • V8

    • 자바스크립트 대표적인 엔진: Google V8 엔진
    • C++로 작성됨.
    • Chrome, Node.js에서 사용됨.
  • JavaScript Core

    • 애플에서 개발하여, WebKit 프레임워크를 위해 개발됨.
    • Safari와 React Native App에서 사용됨.

자바스크립트 구동 원리

1) 바이트 코드로의 변환

  • 자바스크립트 엔진에 의해 바이트 코드로 변환됨.

2) 기계어로 변환

  • CPU마다 기계어를 다르게 해석하기에 가상 머신은 최적화된 기계어 제작함.
  • 개발자는 따로 CPU별로 최적화된 기계어를 제작할 필요가 없음.

3) CPU 코드 실행

  • 기계어를 실행하여 데이터 저장 및 연산 작업을 진행함.

Tokenizer ➡️ Parser ➡️ AST ➡️ 인터프리터

가비지 콜렉터

  • 변수 선언 시 새로운 메모리 공간을 할당하므로, 불필요한 값들이 쌓임.이러한 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제됨. 단, 메모리에서 언제 해제될지는 예측할 수 없음.
  • 자바스크립트의 경우 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당 **개발자의 직접적인 메모리 제어를 허용하지 않음. **➡️ 개발자가 명시적으로 메모리를 할당하고 해제할 수 없음.
  1. Reference-calling: 어떤 다른 객체를 참조하지 않는 객체를 더이상 필요없다고 판단함. ⚠️ 한계점: 두 객체가 서로 참조하는 속성이 될 경우에는 순환구조가 생성되고 메모리 누수가 발생한다. (가비지 생성 불가능함.) => 현재 참조 카운팅은 js 엔진에서 더이상 지원하지 않음.
  2. Mark-and-Sweep: 루트 객체로부터 도달할 수 없는 객체를 더이상 필요없다고 판단함. ⚠️ 순환 구조가 있다고 해도 함수 호출 리턴된 이후에는 두 개의 객체들이 더이상 전역 객체에서 참조되지 않게 되어 메모리 누수가 발생하지 않음.

1. 변수의 목적

평가를 위해서는 literal, operator의 의미를 알아야 한다. 또한, 표현식의 의미 해석(parsing)도 필요하다. => JS 엔진은 피연산자(operand)를 기억한다. 연산(cpu)와 기억(메모리)를 수행하는 영역이 따로 존재한다. 메모리를 통해 데이터를 특정 단위로 읽고 저장하는데, 메모리 주소를 통해 값에 접근하면 오류 발생 가능성이 높아진다. 그래서 JS에서는 객체가 생성되었을 때 자동으로 메모리를 할당하고 더이상 필요하지 않을 때 자동으로 해체하는 과정을 거치도록 한다.

  • 변수 == 값을 저장한 메모리를 식별하기 위한 것 / 값의 위치를 가리킴 => 프로그래밍 언어가 기억하고싶은 값을 메모리에 저장하고, 저장된 값을 읽어들여 "재사용"하기 위함
  • 배열, 객체와 같은 자료구조를 사용하면 여러 개 값을 그룹화하여 하나의 값처럼 사용
  • 변수명 == 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름
  • 변수값 == 변수에 저장된 값
  • 할당(대입,저장) == 변수에 저장하는 행위
  • 참조 == 변수에 저장된 값을 읽어 들이는 것
  • 참조 요청시, 자바스크립트 엔진은 변수명과 매핑된 메모리 주소를 통해 메모리 공간에 접근해 저장된 값을 반환함.

2. 식별자

  • 어떤 값을 구별해서 식별할 수 있는 고유한 이름
  • 같은 값이 메모리 공간에 저장되어 있어도 식별자는 각 값들의 메모리 주소 또한 저장하기 때문에 값을 구별해낼 수 있음.
  • 변수, 함수, 클래스 등 모두 식별자로 구분 가능
  • 선언에 의해 자바스크립트 엔진에 식별자의 존재를 알림

3. 변수 선언

  • 변수를 생성하는 것
    • 값을 저장하기 위한 메모리 공간 확보한 후 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비
    • 변수 선언으로 확보된 메모리 공간은 해제되기 전까지 다른 변수가 사용할 수 없도록 보호됨.
  • var, let, const
    • ES6 도입 때, let, const 변수 선언 키워드가 도입됨

      종류 특징
      var - 함수 스코프
      - 호이스팅 불가능, undefined로 초기화됨
      - 중복 선언 가능
      let - 블록 스코프
      - 호이스팅 가능, 초기화 X, 선언 전 접근 시 Reference Error 발생
      const - 블록 스코프
      - 재할당 불가능
      - 선언과 동시에 초기화 진행 필수

스코프란

  • 함수가 실행될 떄, 함수 내 변수에 대한 접근이 어떻게 되는지
  • 변수에 접근할 수 있는 범위
  1. 함수 스코프 == 지역 스코프
  • 새로운 함수가 생성될 때마다 새로운 스코프 발생
if(5 > 4) {
	var secret = '12345';
}
secret // '12345'
  • 함수 선언하지 않을 시, 새로운 환경 및 스코프가 생성되지 않음
  • 스코프가 형성되지 않아 동일한 실행 컨텍스트 내 존재

function a() { var secret = '12345'; } secret; //ReferenceError

> - 함수 a에 대한 새로운 실행 컨텍스트 생성됨
> - 실행 컨텍스트 내부에 존재하는 변수 환경에 secret 변수가 저장됨.
> - 함수 외부에서 secret 접근 시, 스코프가 다르기 때문에 해당 변수에 접근 불가능함.
> 2. 블록 스코프
> - 블록{}이 생성될 때 새로운 스코프 생성됨
> ```js
function loop() {
	for(var i = 0; i < 5; i++) {
		console.log(i);
	}
	console.log('final',i);
}
loop();
/*
	0
	1
	2
	3
	4
	final 5
*/
  • 접근 가능
  • 자바스크립트 엔진은 변수 선언을 "선언 단계+초기화 단계"에 거쳐 수행한다.
    1. 선언 단계: 변수 이름 등록하여 존재를 엔진에게 알림
    2. 초기화 단계: 값을 저장하기 위한 메모리 공간 확보하고 undefinded로 초기화
  • 변수 선언 시, 모든 식별자는 실행 컨텍스트에 등록됨. 실행 컨텍스트에는 코드를 실행하기 위한 환경 정보를 담아놓은 객체. 해당 객체에는 변수 객체, 스코프, this 정보가 담겨있음.
  • ReferenceError: 참조되지 않은 값을 식별자가 접근하려고 할 때 나는 에러가 var 선언 시에는 발생하지 않는다. JS엔진은 변수 선언을 가장 먼저 실행(== 호이스팅)시키는데, var 키워드는 선언+초기화가 동시에 진행되기 때문이다.

4. 변수 선언의 실행 시점과 변수 호이스팅

console.log(score);	// undefined

var score; // 변수 선언문
  • 변수를 참조하는 코드가 변수 선언문보다 앞에 있음에도 ReferencError가 나지 않는 이유:
  • 변수 선언은 소스 코드가 한 줄씩 순차적으로 실행되는 시점(런타임) 이전 단계에서 먼저 실행됨. == 호이스팅
  • 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징
  • 모든 식별자는 호이스팅됨 (변수, 함수, 클래스 등)

5. 값의 할당

var score;	// 변수 선언
score = 80;	// 값의 할당

⚠️ 변수 선언과 값의 할당의 실행 시점은 다르다

  • 변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행됨
  • 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임 때 실행됨
console.log(score);	// undefined

var score;	// 변수 선언
score = 80;	// 값의 할당

console.log(score);	// 80
  • 변수에 값을 할당할 때 이전 값 undefined가 저장되어 있던 메모리 공간을 지우고 그 메모리 공간에 할당 값 80을 새롭게 저장하는 것이 아니라, 새로운 메모리 공간을 확보하고 할당 값 80을 저장함

6. 값의 재할당

  • 이미 값이 할당되어 있는 변수에 새로운 값을 다시 할당하는 것 == 재할당
  • 변수에 저장된 값을 변경할 수 없는 것 == 상수
    • 사실 var는 선언 하자마자 undefined로 초기화되기 때문에 값을 할당하면, 이것도 재할당에 해당함
    • const로 선언된 변수는 재할당이 불가능하다. => const로 상수 표현 가능

7. 식별자 네이밍 규칙

  • 변수나 함수 이름 == 카멜 케이스
  • 생성자 함수, 클래스 이름 == 파스칼 케이스