JavaScript 변수!
읽을거리 - 자바 스크립트 시리즈
자바스크립트 엔진은 V8(크롬과 Node), SpiderMonkey(파이어폭스), JavaScriptCore(사파리) 등 다양한 종류가 있으며, 모든 자바스크립트 엔진은 ECMAScript 사양을 준수한다
https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-엔진-런타임-콜스택-개관-ea47917c8442
자바스크립트는 어떻게 작동하는가: 엔진, 런타임, 콜스택 개관
How JavaScript works: an overview of the engine, the runtime, and the call stack
https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-v8-엔진의-내부-최적화된-코드를-작성을-위한-다섯-가지-팁-6c6f9832c1d9
자바스크립트는 어떻게 작동하는가: V8 엔진의 내부 + 최적화된 코드를 작성을 위한 다섯 가지 팁
How JavaScript works: inside the V8 engine + 5 tips on how to write optimized code
https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-메모리-관리-4가지-흔한-메모리-누수-대처법-5b0d217d788d
자바스크립트는 어떻게 작동하는가: 메모리 관리 + 4가지 흔한 메모리 누수 대처법
How JavaScript works: memory management + how to handle 4 common memory leaks
https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-이벤트-루프와-비동기-프로그래밍의-부상-async-await을-이용한-코딩-팁-다섯-가지-df65ffb4e7e
자바스크립트는 어떻게 작동하는가: 이벤트 루프와 비동기 프로그래밍의 부상, async/await을 이용한 코딩 팁 다섯 가지
How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding with async/await
https://engineering.huiseoul.com/자바스크립트는-어떻게-작동하는가-웹소켓-및-http-2-sse-1ccde9f9dc51
자바스크립트는 어떻게 작동하는가: 웹소켓 및 HTTP/2 SSE
How JavaScript works: Deep dive into WebSockets and HTTP/2 with SSE + how to pick the right path
http://hacks.mozilla.or.kr/category/es6-in-depth/
ES2016에 대한 설명
변수 개요
1 | var x = 100; |
리터럴값 100 을 변수 x 가 참조하는 변순선언 및 할당문
JS 에선 밑의 hoisting 으로 인해 위와같이 변수 선언 할당 한줄처리도x 가 undefined 으로 설정 후 100 으로 할당된다.
literal: 정확한
변수타입은 아래와 같다.
number- 숫자를 모두 실수로 표현, 64bit 부동소수점 형식stringboolean-true,falseundefined- var 에 설정된 암묵적인 값null- 의도적으로 값이 없음을 명시, 가비지콜렉터 호출예약symbol- 변경 불가능한 원시 타입의 값object- 객체, 함수, 배열 등
1 | console.log(typeof "admin"); //string |
hoisting
hoisiting: 끌어 올리기
실행 컨텍스트 생성시 var, function, class 같은
일부 키워드를 먼저 읽어 변수를 미리 생성한다.
1 | x = 20; |
1 | console.log(multi(1, 2)); |
ES2015 등장 전까진 var 키워드로 변수생성을 자주 했었다.var 는 hoisting 가능한 키워드이기도 하고 중복선언 스코프에서도 어느정도 자유로운면이 있어 편하지만 혼란을 주는 키워드라 권장하지 않는다.
이를 막고싶다면 use strict 키워드를 사용
Strict mode: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode
1 | ; |
use strict사용은 권장하지 않는다, 라이브러리별로 strict mode 가 다를 수 있으며 같은 JS 파일 안에서 strict mode 가 변경되면서 발생하는 오류가 있을 수 있다.
hosting 의존적인 코드를 제거하는 것을 권장한다.
원시타입(primitive type)
원시타입의 값들은 변경 불가능한 값(immutable value) 이다.
JS 에선 원시타입을 메모리공간에 할당해서 read 만 할 수 있을 뿐
같은 메모리 공간에 다른 원시타입을 덮어씌우거나 할 수 없다
원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다
1 | var score = 80; |
또한 score, copy 변수는 같은 메모리 위치의 원시타입을 참조할 것 같지만
다른 메모리 공간에 저장된 별개의 값이다.

python 의 경우 같은 위치의 원시타입을 참조함
스코프
ES2015 이후에 추가되었으며 아래 3가지 스코프 존재
global scopelocal scope-function scope로 부르기도 함,var변수가 종속됨block scope-let변수가 종속됨
local이block과function을 포함한다고 소개하는 글도 있음
let, const 키워드를 사용해 블록범위 변수를 선언한다.
전역과 지역 범위는 아래와 같다.
1 | // global scope |
스코프 체인
1 | var x = "global x" |
위와 같이 중복함수가 정의된 상태에서 global scope 와 local scope 변수를 찾아가는 조건이 있다.
outer 함수와 inner 함수는 모두 자신만의 local scope 를 가지고 있는데하위 local scope -> 상위 local scope -> global scope 방향으로 흐른다.
lexical 스코프
dynamic scope: 함수 호출시점에 상위 스코프 결정lexical scope:static scope라 하기도 하며 함수 정의 위치에 따라 상위 스코프 결정
JS 는 lexical scope 이고 대부분의 언어가 lexical scope 이다.
1 | var x = 1; |
bar 의 정의위치가 foo 의 내부(중첩함수)가 아니기에 상위 스코프는 global scope, 가장 외부의 x 를 참조한다.
변수 키워드
JS 에서는 별도의 변수타입 없이 var, let, const 등으로 바로 변수 생성한다.
var
var 변수는 local scope 에 종속된다.
아래처럼 block scope 에서 정의될 경우 종속되지 않아 전역변수로 정의된다(암묵적 전역).
1 | for (var i = 0; i < 10; i++) { |
for 의 인덱스용 변수 var i 도 전역변수로 등록되어 오류를 야기할 수 있다.
local scope 에 정의될 경우 그 안에서만 사용되고 밖으로 나올순 없다.
1 | function test() { |
var 의 경우 아래처럼 중복정의될 가능성이 있고
실수로 전역변수로 정의될 수 있음으로 사용자체를 권장하지 않는다.
1 | var test = 10 |
let
let 은 block scope 에 종속된다.
아래처럼 블록내부에서 정의되면 블록 내부에서만 사용 가능하다.
1 | { |
하위블록에서 사용가능하고 변경도 가능하다.
같은스코프에서는 중복정의가 불가능하며
블록 레벨이 다를경우 재정의 가능하다.
하지만 블록내부에서 재정의할 경우 기존 let 변수를 변경하는 것이 아닌 새로운 변수를 생성하기에 밖의 let 변수와는 상관이 없어진다.
1 | let x = 'global' |
let을 사용하면 다음과 같은 논리오류를 방지할 수 있다.
1 | var i = 5; |
let 은 hoisting 대상이지만 미리 사용하는것이 불가능하다. 이 상황을 TDZ(temporal dead zone) 이라 한다.
1 | console.log(num) // ReferenceError: Cannot access 'num' before initialization |
const
대부분 let 과 비슷하나const 로 변수를 선언할 경우 값이 변경되지 않도록 고정 가능하다.
1 | const num1 = 10; |
var vs. let vs. const
개인적으로 생각하는 변수 키워드 우선순위
- 기본적으로 const 를 사용하자
- 작은 스코프의 로컬 변수에는 let 을 사용한다
- 재할당이 필요한 경우에만 let 을 사용하자
- 코드 작성이 어느 정도 진행된 후에만 let 을 const 로 리팩터링한다. 변수 재할당을 막아야 하는 경우라는 것이 확실해야 한다
- var 는 ES6 에서 절대 사용하지 않는다
- 전역변수 생성은 고심끝에(메모리 해재되지 않음)
타입 변환
명시적 타입변환(explicit coercion)
타입캐스팅(type casting) 이라고도 하며 타입변환을 코드로 명시하는 것
1 | // 1. String 생성자 함수를 new 연산자 없이 호출하는 방법 |
암묵적 타입변환(implicit coercion)
위의 두가지 상황에서 암묵적 타입변환에 대해 알아본다.
to string
1 | // 숫자 타입 |
to number
1 | // 문자열 타입 |
Truthy, Falsy
대부분의 변수들은 if 문에서 사용되면 암시적으로 true 혹은 false 로 변환하게 된다.
이를 Truthy, Falsy 한 변수라 칭한다.
아래는 false 로 암시적 변환되는 변수타입, 값 들이다.
1 | console.log(Boolean(false)) // false |
반대로 true 로 암시적 변환되는 값
1 | console.log(Boolean(1)) // true |