Variable in JS

14 Oct 2015

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

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

      ```javascript
          
      // 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 내부

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

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

      ```javascript
            
      // 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속성으로 추가된다

        ```javascript
        // 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 함수

        ```javascript
                
        // 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 내부

        ```javascript
        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

comments powered by Disqus