keyward 재할당의 여부

A. 정의

  1. 데이터를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간

  2. 값의 상징적인 이름으로 변수를 사용한다

  3. 변수명은 식별자(Identifier)라고 불리며 특정 규칙을 따른다

    i) 식별자는 문자, 밑줄(_) 혹은 달러 기호($)로 시작해야한다

    ii) 문자는 대,소문자를 구분한다

B. 변수의 선언과 할당

  1. 변수는 아래 3가지 방법으로 선언이 가능하다

    i) var 키워드로 선언

    var x = 42 // x라는 변수에 42를 할당
    

    ii) let 키워드로 선언

    let y = 24 // y라는 변수에 24를 할당
    

    iii) 식별자 없이 변수에 할당

    z = 20 // z라는 변수에 20을 할당
    
  2. 변수는 선언과 동시에 할당이 가능하고, 아무런 값을 할당하지 않는다면 값이 할당되기 전까지 undefined 값을 갖게 된다.

    var x; // undefined
    let y; // undefined
    
  3. 선언되지 않은 변수에 접근을 시도하는 경우 ReferenceError 예외가 발생한다

    let x = 20;
    
    console.log(y) //ReferenceError 
    

C. 변수의 종류와 상수

  1. 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"
        }
    }
    
  2. 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' 
}
*/