Variable in JS

October 14, 2015

  • ECMAScript 에서 말하는 변수는 오직 var 키워드를(또는 변수 선언식을) 통해서만 선언된다.

    • var 키워드가(또는 변수 선언식이) 생략된 y 속성은, 변수가 아닌 VO속성일 뿐이며, Execution Context 진입 시, VO 의 새로운 속성으로 추가되지 않는다.

      
      // global Execution Context
      
      // var 키워드를(변수 선언식을) 통해 변수가 선언되었다.
      // Execution Context 진입 시 VO 의 새로운 속성으로 추가되며, undefined 로 초기화된다.
      console.log(this.x); // undefined
      console.log(x); // undefined
      
      // var 키워드를 통한 변수 선언
      var x = 1;
      
      
      try{
      
        // Execution Context 진입 시 VO 의 새로운 속성으로 추가되지않으며, 그에 따라 런타임 에러가 발생한다.
        console.log(y);
      }
      catch(ex){
        console.log(ex.message); // y is not defined
      }
      
      
      // var 키워드가(변수 선언식이) 생략된 y 속성
      y = 2;
      
    • Execution Context 진입 시 ECStack 내부

      var ECStack = [
        globalExecutionContext: {
          VO: {
            x: undefined
            // y 속성은 execution context 진입 시 초기화되지 않는다.
          }
        }
      ];
    • 실행 코드 처리 후에는 VO 의 새로운 속성으로 추가된다.

      
      // global Execution Context
      
      // Execution Context 진입 시 VO 의 새로운 속성으로 추가되지않는다.
      y = 2; // 실행 코드
      
      // 실행 코드 처리 후에는 VO 의 속성으로 추가된다.
      console.log(y); // 2
      console.log(this.y); // 2
    • 변수 선언식을 통해, 생성된 변수non-configurable(or DontDelete) 속성으로 정의되며, delete 연산자를 통해 삭제되지 않는다.

      
      // global Execution Context
      
      // var 키워드를 통한 x 변수는 non-configurable 속성을 가지고있다.
      // configurable = false
      var x = 1;
      
      // var 키워드가 생략된 y 속성은 configurable 속성을 가지고있다.
      // configurable = true
      y = 2;
      
      
      // Object {value: 1, writable: true, enumerable: true, configurable: false}
      console.log(Object.getOwnPropertyDescriptor(this, 'x'));
      
      // Object {value: 2, writable: true, enumerable: true, configurable: true}
      console.log(Object.getOwnPropertyDescriptor(this, 'y'));
      
      // delete 연산자를 통해 x 변수를 삭제한다.
      delete this.x;
      
      // delete 연산자를 통해 y 속성을 삭제한다.
      delete this.y;
      
      // x 변수는 non-configurable 속성으로 delete 연산자를 통해, 삭제되지 않는다.
      console.log(x); // 1
      
      // y 속성은 configurable 속성으로 delete 연산자를 통해, 삭제된다.
      console.log(this.y); // undefined
    • eval 함수를 통해, 선언된 변수변수로 선언되지 않는다.(VO속성으로 추가되며, configuration 속성으로 정의된다)

      • 변수가 아닌, VO속성으로 추가된다

        // global Execution Context
        
        // calling context 는 global Execution Context 를 가리킨다.
        
        // eval 함수를 통해 x 변수를 생성한다.
        eval('var x = 1');
        
        // 정의된 객체 속성을 나열한다.(x 속성은 configurable 속성으로 정의되어있다)
        
        // Object {value: 1, writable: true, enumerable: true, configurable: true}
        console.log(Object.getOwnPropertyDescriptor(this, 'x'));
        
        console.log(this.x); // 1
        
        // delete 연산자를 통해 x 속성을 삭제한다.
        delete this.x;
        
        // 변수가 아닌, VO 의 x 속성은 delete 연산자를 통해 삭제된다.
        // 즉 configurable 속성으로 정의되었으며, 변수로 선언되지 않았다.
        console.log(this.x); // undefined
        
      • Function Execution Context 의 eval 함수

        
        // global execution context
        
        function A() {
        
            // function execution context
        
            // calling context 는 function execution context 를 가리킨다.
        
            // x 지역 변수를 선언한다.
            var x = 1;
        
            // eval 함수를 통해, 변수를 선언한다.
            eval('var y = 2;');
        
            console.log(x); // 1
        
            // y 속성은 calling context 내부 VO 에 추가된다.
            console.log(y); // 2
        
            // x 변수를 delete 연산자를 통해 삭제한다.
            delete x;
            // y 속성을 delete 연산자를 통해 삭제한다.
            delete y;
        
            // x 변수는 delete 연산자를 통해, 삭제되지 않는다.
            // 즉 x 변수는 변수로 선언되었다.(DontDelete 속성)
            console.log(x); // 1
        
            // delete 연산자를 통해, 해당 속성이 삭제되었다.
            // 즉 y 속성은 변수로 선언되지 않았다.
            console.log(y); // Uncaught ReferenceError: y is not defined
        }
        
        A();
      • ECStack 내부

        var ECStack = [
          evalExecutionContext: {
            VO: {
              y: 2
            }
          },                
          // 호출 문맥
          callingContext: <A> functionExecutionContext,
          <A> functionExecutionContext: {
            AO(VO): {            
              // 실행 코드 처리 후, x 변수에 1이 할당된다.      
              x: 1, // --> delete 연산자를 통해 삭제되지 않는다. --> 1
              // eval 함수로 전달된 실행 코드로 인해, calling context 내부 VO 가 영향받는다.
              y: 2 // --> delete 연산자를 통해 삭제된다. --> y is not defined
            }
          },
          globalExecutionContext: {
            VO: {
              A: < reference to function >
            }
          }
        ];

참고 URL


Profile picture

Written by mohwa