💡 (js를 해석하고 실행하는)자바스크립트 엔진이 10 + 20을 어떻게 계산할까?
컴퓨터에선 CPU - 연산, 메모리 - 데이터 기억 이렇게 역할이 나누어져있다
(+) 연산을 하기 위해 10과 20(피연산자)를 메모리에 저장함(2진수로 저장됨)
연산 후 결과값인 30도 메모리에 저장함
그치만 문제 : 연산해서 만든 값인 30을 재사용할 수 없음!
-> 재사용하고 싶다면 30이 저장돼있는 메모리 주소를 통해 30이저장된 메모리 공간에 직접 접근 해야함
-> but 이건 오류 발생 가능성 높음 위험함
& 동일한 코드를 실행해도 실행될 때마다 값이 저장될 메모리 주소는 변함
=> js는 개발자의 직접적인 메모리 제어를 허용 x
// 변수는 하나의 값을 저장하기 위한 수단임
var userId = 1;
var userName = 'Lee';
// 객체/배열 같은 자료구조를 사용하면 #개의 값을 하나로 그룹화해서 하나의 값처럼 사용 가능
var user = { id: 1, name: 'Lee' };
var users = [// 객체로 이루어진 배열
{ id: 1, name: 'Lee' },
{ id: 2, name: 'Kim' }
];
-> 식별자 - 메모리 공간에 저장돼있는 어떤 값을 구별해서 식별할 수 있어야 함
-> 식별자 - 어떤 값이 저장돼 있는 메모리 주소를 기억(저장)해야 함
=> 즉, 식별자 - 값이 저장돼 있는 메모리 주소와 매핑 관계를 맺음 & 이 매핑 정보도 메모리에 저장돼야 함
💡✏️ 변수 이름은 어디에 등록되는가?
모든 식별자 : 실행 컨텍스트에 등록됨
*) 실행 컨텍스트(execution context) : JS 엔진이 소스코드 평가 & 실행하기 위해 필요한 환경 제공 , 코드의 실행 결과를 실제로 관리하는 영역
변수 이름 & 변수 값 : key/value 형식인 객체로 등록됨
변수 선언 = 변수 생성
값 저장하기 위한 메모리 공간 확보 & 확보된 메모리 공간의 주소를 연결 -> 값을 저장할 수 있게 준비하는 것
var 키워드 : 뒤에 오는 변수 이름으로 새로운 변수를 선언할 것을 지시함
*) var 키워드의 단점 : 블록 레벨 스코프 지원 X, 함수 레벨 스코프 지원 -> 의도치 않게 전역 변수 선언될 수 O
var score; // 변수 선언
변수 선언문 - 변수 이름 등록 & 값 저장할 메모리 공간 확보
-> 아직 변수에 값 할당 안 함
=> 자바스크립트 엔진에 의해 undefined 라는 값이 암묵적으로 할당돼서 초기화됨
undefined : JS에서 제공하는 원시 타입의 값
1) 선언 단계 : 변수 이름을 등록해서 js 엔진에 변수의 존재를 알림
2) 초기화 단계 : 값 저장하기 위한 메모리 공간 확보 & 암묵적으로 undefined 할당하여 초기화
선언하지 않은 식별자에 접근 -> ReferenceError(참조 에러) 발생
console.log(score); //undefined 출력
var score; // 변수 선언문
❓ 위의 코드에서 Reference Error가 발생할 것 같지만, undefined가 출력됨
🔍 why?
변수 선언이 런타임(= 소스코드가 1줄씩 순차적으로 실행되는 시점)이 아니라, 그 이전 단계에서 먼저 실행되기 때문
1) JS 엔진 - 소스코드 1줄씩 순차적으로 실행하기 전 소스코드 평가 과정 거침
-> 모든 선언문(변수 선언문, 함수 선언문...)을 소스코드에서 찾아내서 먼저 실행함
2) 소스코드 평가 과정 끝나면 모든 선언문을 제외하고 소스코드를 1줄씩 순차적으로 실행함
변수 호이스팅(variable hoisting) : 변수 선언문이 코드의 맨 위로 끌어 올려진 것처럼 동작하는 JS 고유 특징
변수에 값을 할당할 땐 할당 연산자 = 을 사용함
-> 우변의 값을 좌변의 변수에 할당함
var score; // 변수 선언
score = 80; // 값의 할당
var score = 80; // 변수 선언 & 값의 할당을 한 번에 단축 표현함
이 두 코드는 동일하게 동작함
단축 표현해도 변수 선언 & 값의 할당을 2개의 문으로 나누어 각각 실행함
console.log(score); // undefined
var score; // 1) 변수 선언 -> undefined로 초기화됨
score = 80; // 2) 값의 할당
console.log(score); // 80
1), 2)의 순서가 바뀌어도 실행 결과는 같음
재할당 : 이미 값이 할당돼 있는 변수에 새로운 값을 다시 할당하는 것
var 키워드로 선언한 변수는 값 재할당 가능
값을 재할당 할 수 X -> 변수가 아니라 상수임
💡 const 키워드로 선언한 변수는 값 재할당 불가능
var score = 80;
score = 90;
-> 80이 저장돼 있던 메모리 공간을 지우고 거기에 90 저장하는게 아니라, 새로운 메모리 공간 확보하고 거기에 90 저장
score 변수의 이전 값인 undefined, 80은 어떤 식별자와도 연결돼 있지 X
이런 불필요한 값 -> 가비지 콜렉터(garbage collector)에 의해 메모리에서 자동 해제됨
💡 garbage collector : 애플리케이션이 할당한 메모리 공간을 주기적으로 검사해 더 이상 사용되지 않는 메모리(어떤 식별자도 참조하지 않는 메모리 공간)를 해제하는 기능
<예약어>
await | break | case | catch | class | const |
---|---|---|---|---|---|
continue | debugger | default | delete | do | else |
enum | export | extends | false | finally | for |
function | if | implements | import | in | instanceof |
interface | let | new | null | package | private |
proteted | public | return | super | static | switch |
this | throw | true | try | typeof | var |
void | while | with | yield |
var person, $elem, _name, first_name, val1; // 이렇게 변수 #개를 한 번에 선언 가능하지만 가독성 bad
// 카멜 케이스(camelCase)
var firstName;
// 스네이크 케이스(snake_case)
var first_name;
// 파스칼 케이스(PascalCase)
var FirstName;
// 헝가리언 케이스(typeHungarianCase)
var strFirstName; // type + identifier
var $elem = document.getElementById('myId'); // DOM 노드
var obserable$ = fromEvent(document, 'click'); // RxJS 옵저버블