Languages/JavaScript

[HUFS/GnuVil] #1 변수, 표현식과 문

성중 2022. 9. 14. 02:40

변수

10 + 20

 

자바스크립트 엔진은 위 자바스크립트 코드를 계산(=평가, evaluation)하기위해 리터럴(literal)연산자(operator)의 의미를 알고 있어야 하며 표현식(expression)의 의미도 해석(=파싱, parsing)할 수 있어야 한다. 이 때 메모리를 사용해 피연산자를 기억하며, 연산은 CPU를 통해 이루어진다

 

메모리는 1바이트(8비트) 크기의 메모리 셀로 구성

각 셀은 고유의 메모리 주소를 가지며 모든 데이터를 2진수로 처리한다

 

연산 결과 또한 메모리에 저장

재사용을 위해 메모리 주소로 직접 연산 결과에 접근하는 것은 시스템에 치명적인 오류를 발생시킬 수 있다. 따라서 변수(variable)를 활용해 하나의 값을 저장하기 위한 메모리 공간 확보 및 식별하기 위한 이름을 붙인다. 이는 컴파일러 또는 인터프리터에 의해 메모리 공간의 주소로 치환되어 실행된다

 

var result = 10 + 20;

 이렇게 변수에 값을 할당(assignment)/대입/저장하면 저장된 값을 참조(reference)할 수 있다

 

값의 생성과 변수에의 할당

변수명은 식별자(identifier)라고도 하며 선언(declaration)을 통해 존재를 알린다

 

이 때, 식별자는 값이 아닌 메모리 주소를 기억하며, 매핑 정보도 메모리에 저장

var score; // 변수 선언(변수 선언문)

위와 같이 선언하면 확보된 메모리 공간에는 undefined가 암묵적으로 할당되어 초기화된다

초기화(initialization)란 변수가 선언된 이후 최초로 값을 할당하는 것이며, var 키워드의 경우 변수 선언 단계와 초기화 단계가 동시에 진행된다

* 만약 초기화 단계를 거치지 않으면 확보된 메모리 공간에 이전 어플리케이션에서 사용했던 쓰레기 값(garbage value)이 남아있을 수 있다!

 

선언하지 않은 식별자에 접근하면 ReferenceError(참조 에러) 발생

console.log(score); // undefined

var score; // 변수 선언문

위와 같이 선언 이전에 참조하는 경우, 참조 에러 발생하지 않고 undefined가 출력된다

이는 변수 선언이 런타임(runtime)이 아닌 그 이전에 이미 실행되기 때문이다

이러한 자바스크립트 고유의 특징을 호이스팅(variable hoisting)이라고 한다

* 변수 선언 외에 일부 키워드는 TDZ(Temporal Dead Zone)에 영향을 받기 때문에 호이스팅이 될 수 있어도 해당 변수들은 사용할 수 없고, 참조 에러가 발생한다

 

console.log(score); // undefined

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

console.log(score); // 80

변수 선언은 런타임 이전에 실행되지만 (호이스팅), 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다

 

console.log(score); // undefined

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

console.log(score); // 80

따라서 위와 같은 경우에도 동일한 결과가 나온다

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

재할당이란 이미 값이 할당되어 있는 변수에 새로운 값을 다시 할당하는 것이다

* 값을 재할당하는 것이 불가능하다면 변수가 아닌 상수(constant)라고 한다

 

새로운 메모리 공간에 값을 재할당

이후 식별자가 참조하지 않는 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제된다

 

식별자는 다음과 같은 네이밍 규칙을 준수한다

  • 식별자는 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다
  • 단, 식별자는 숫자로 시작하는 것은 허용하지 않는다
  • 예약어(키워드)는 식별자로 사용할 수 없다

 

자바스크립트 예약어

// 카멜 케이스 (camelCase)
var firstName;

// 스네이크 케이스 (snake_case)
var first_name;

// 파스칼 케이스 (PascalCase)
var FirstName;

// 헝가리언 케이스 (typeHungarianCase)
var strFirstName; // type + identifier
var $elem = document.getElementById('myId'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블

위 4가지 유형의 네이밍 컨벤션이 자주 사용된다

 

표현식과 문

// 10 + 20은 평가되어 숫자 값 30을 생성한다.

10 + 20; // 30

값(value)이란 표현식(expression)이 평가(evaluate)되어 생성된 결과를 뜻한다

 

// 숫자 리터럴 3

3

리터럴(literal)은 사람이 이해할 수 있는 문자 또는 약속된 기호로 값을 생성하는 표기법이다

 

리터럴 종류

// 리터럴 표현식
10
'Hello'

// 식별자 표현식(선언이 이미 존재한다고 가정)
sum
person.name
arr[1]

// 연산자 표현식
10 + 20
sum = 10
sum !== 10

// 함수/메서드 호출 표현식(선언이 이미 존재한다고 가정)
square()
person.getName()

표현식(expression)은 값을 생성하거나 기존 값을 참조해 값으로 평가될 수 있는 문이다

* 이 때, 표현식과 표현식이 평가된 값은 동등한 관계 (=동치, equivalent)

 

var x = 1 + 2;

// 식별자 표현식 x는 3으로 평가된다.
x + 3; // -> 6

표현식은 다른 표현식의 일부가 되어 새로운 값을 만들어 낼 수 있다

// 변수 선언문
var x;

// 표현식 문(할당문)
x = 5;

// 함수 선언문
function foo () {}

// 조건문
if (x > 1) { console.log(x); }

// 반복문
for (var i = 0; i < 2; i++) { console.log(i); }

문(statement)이란 프로그램을 구성하는 최소 실행 단위이며 선언문, 할당문, 조건문, 반복문 등으로 구분된다

 

// 변수 선언문은 값으로 평가될 수 없으므로 표현식이 아니다.
var x;
// 1, 2, 1 + 2, x = 1 + 2는 모두 표현식이다.
// x = 1 + 2는 표현식이면서 완전한 문이기도 하다.
x = 1 + 2;

표현식은 문의 일부일 수도 있고 그 자체로 문이 될 수도 있다

 

// 표현식이 아닌 문은 값처럼 사용할 수 없다.
var foo = var x; // SyntaxError: Unexpected token var

표현식인 문과 표현식이 아닌 문을 구별하는 가장 간단한 방법은 변수에 할당해보는 것이다

 

내용은 위키북스의 '모던 자바스크립트 Deep Dive' 바탕으로 작성되었습니다.