keyward 재할당의 여부
A. 정의
데이터를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간
값의 상징적인 이름으로 변수를 사용한다
변수명은 식별자(Identifier)라고 불리며 특정 규칙을 따른다
i) 식별자는 문자, 밑줄(_) 혹은 달러 기호($)로 시작해야한다
ii) 문자는 대,소문자를 구분한다
B. 변수의 선언과 할당
변수는 아래 3가지 방법으로 선언이 가능하다
i) var 키워드로 선언
var x = 42 // x라는 변수에 42를 할당
ii) let 키워드로 선언
let y = 24 // y라는 변수에 24를 할당
iii) 식별자 없이 변수에 할당
z = 20 // z라는 변수에 20을 할당
변수는 선언과 동시에 할당이 가능하고, 아무런 값을 할당하지 않는다면 값이 할당되기 전까지 undefined 값을 갖게 된다.
var x; // undefined
let y; // undefined
선언되지 않은 변수에 접근을 시도하는 경우 ReferenceError 예외가 발생한다
let x = 20;
console.log(y) //ReferenceError
C. 변수의 종류와 상수
var
i) 구문
var 변수명 = 값;
ii) 특징
a) var로 선언한 변수는 함수 스코프거나 전역 스코프이다
b) 같은 변수명으로 재선언하면 이전 변수는 무시되고 새로운 변수로 작동한다
var user = "Kim" //무시됌
var user = "choi"
c) var로 선언된 변수들은 값 할당이 실행될 때 전역변수처럼 생성이 되고 전역 객체의 속성값이 된다.
d) 호이스팅이 발생할 수 있다. 이때 var의 스코프는 함수 스코프이거나 전역스코프 이기 때문에 선언 위치에 상관없이 끌어올려져 해당 함수의 유효범위 최상단에서 선언된다.
//eg 1
console.log(a); // outputs 'undefined'
var a = 3;
//eg 2
function test(){
console.log(n) // outputs 'undefined'
var n = 2
console.log(n) // outputs 2
}
test();
//eg 3
function test2(){
console.log(test) // outputs 'undefined'
if(false){
var test = "test"
}
}
let
i) 구문
let 변수명 = 값;
ii) 특징
a) let으로 선언된 변수는 변수가 선언된 블록 및 하위 블록에서 유효 (블록 스코프)
b) var와는 다르게 최상위에서 선언된다고 하더라도 전역 객체의 속성 값을 생성하지 않는다.
var x = 'global';
let y = 'global';
console.log(this.x);
// "global" 전역 객체의 속성 x를 생성
console.log(this.y);
// undefined 전역 객체의 속성 y를 생성하지 않음
c) 같은 변수명으로 변수를 재선언할 때 원래의 변수와 같은 블록 범위 내라면 syntaxError가 발생한다.
if (x) {
let foo;
let foo; // SyntaxError thrown.
}
d) 호이스팅이 되어도 자바스크립트 엔진에 의해 할당이 평가되기 전까진 실행되지 않는다. (Temporal Dead Zone)
function test(){
console.log(test)
/* ReferenceError : Cannot access 'test'
before initialization */
let test = "test"
}
test()
3.const
i) 구문
const 변수명 = 값
ii) 특징
a) const는 블록 범위의 상수를 선언한다
b) 선언되는 같은 문에 값을 지정해야한다.
const foo;
/* SyntaxError: Missing initializer in const
declaration */
c) const는 재선언, 재할당이 불가하다.
const foo = 10;
foo = 20;
/*SyntaxError: Identifier 'foo'
has already been declared*/
let foo = 40 // 위와 같음
var foo = 30 // 동일
d) const로 객체를 선언할 시 객체의 재선언, 재할당은 불가하지만 속성의 변경은 보호되지 않는다.
// eg 1
const MY_OBJECT = {'key': 'value'};
MY_OBJECT = {'OTHER_KEY': 'value'};
// TypeError: Assignment to constant variable.
// eg 2
const MY_OBJECT = {
key : "value",
key2 : "value2"
}
MY_OBJECT.key3 = "value3" // 속성 추가
MY_OBJECT.key = " value_changed" // 속성 값 변경
if(MY_OBJECT.hasOwnProperty('key2')){
MY_OBJECT.key2_changed = MY_OBJECT.key2
delete MY_OBJECT.key2 // 속성 변경
}
/* 결과 :
{ key: ' value_changed',
key3: 'value3',
key2_changed: 'value2'
}
*/