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

    Read more


  • javascript 
    • this 값은 Execution Context 의 속성 중 하나이다.

        var ECStack = [
          globalExecutionContext: {
            VO: {
            },
            this: global object
          }
        ];
      

    • this 값은 해당 Execution Context **진입 시 초기화**된 후, 그 이 변하지 않는다.

          
        // global Execution Context
          
        // 실행 코드 처리 시 새로운 값을 할당할 수 없다.
        this.window = null;
      
        // 실행 코드 처리 후 값이 변하지 않는다.
        console.log(this.window); // global object
          
      
    • 레퍼런스 타입(Reference Type)

      • 레퍼런스 타입은 base 와 propertyName 속성을 가진 객체로 표현할 수 있으며, 설명을 목적으로 “ECMA 스펙” 에서 정의하고 있는 개념이다.

        
            // 아래는 레퍼런스 타입을 나타내는 pseudo-code 이다.
            var valueOfReferenceType = {
              base: <base object>,
              propertyName: <property name>
            };
        
        • 레퍼런스 타입은 오직 두 가지 경우에만 있을 수 있다.

          • 식별자(identifier)

            • 식별자는 변수 이름, 함수 이름, 함수 Argument 이름으로 나뉜다.

            • 변수 이름

              
              // global Execution Context
              
              // A 변수 선언
              var A = 1;
              
              console.log(A); // 1
              
            • 레퍼런스 타입 내부

              var AReference = {
                base: global object,
                propertyName: 'A'
              };
              
            • 함수 이름

                // global Execution Context
                              
                // A 함수 선언
                function A(){
                      
                };
                              
                console.log(A); // A function object
                                                  
              
            • 레퍼런스 타입 내부

              ```javascript
              var AReference = {
                base: global object,
                propertyName: 'A'
              };
              ```
              
            • GetValue 메서드

              - <u><strong>객체</strong>(레퍼런스 타입)의 실제 값을 얻기 위해 사용되는 <span style="color:#6298c1">GetValue</span> 메소드가 존재하며</u>, 이 메서드는 <strong>프로토타입 체인</strong>을 통해, 상속된 <strong>속성</strong>까지 모두 분석 후, <strong>객체 속성</strong>(propertyName)의 실제 값을 <strong>반환</strong>해준다.
              
                  ```javascript
                                
                  // GetValue 메서드를 나타내는 pseudo-code 이다.
                  function GetValue(value) {
                                  
                    if (Type(value) != Reference) {
                      // 레퍼런스 타입이 아니면 값을 그대로 돌려준다.
                      return value;
                    }
                                  
                    // base 속성 값을 가져온다.
                    var base = GetBase(value);
                                  
                    // base 속성 값이 null 인 경우
                    if (base === null) {
                      throw new ReferenceError;
                    }
                                  
                    // propertyName 속성 값을 가져온다.
                    var propertyName = GetPropertyName(value);
                                  
                    // [[Get]] 메서드는 프로토타입 체인으로부터, 상속된 속성까지 모두 분석 후 속성의 실제 값을 돌려준다.
                    return base.[[Get]](propertyName);
                                  
                  }
                                
                  GetValue(ReferenceType);
                                
                  ```			
              
          • 프로퍼티 접근자(property accessor)

            • obj 객체의 A 메서드

              ```javascript
              // global Execution Context
                    
              var obj = {
                A: function(){
                  return this;
                }
              };
                    
              console.log(obj.A()); // obj Object
              console.log(obj['A']()); // obj Object
              ```
              
            • 레퍼런스 타입 내부

              ```javascript
              var objAReference = {
                base: obj Object,
                propertyName: 'A'
              };
              ```
              
            • GetValue 메서드를 통해 해당 속성(propertyName) 값을 반환한다.

              ```javascript
              GetValue(objAReference); // A function object
              ```
              
    • 전역 코드 안의 this

      • 전역 코드안의 this전역 객체 자신이된다.

        ```javascript
            
        // global code in global Execution Context
              
        console.log(this); // global object
          
        console.log(this.window); // global object
          
        console.log(this === this.window); // true
        ```
        
    • 함수 코드 안의 this

      • 함수 코드의 경우 this가리키는 **대상**이 매번 달라질 수 있다.

        • Function Execution Context 진입 시 this 가 가지는 초기화 값은 **호출 표현식 형태**에 의해 달라진다.

        • 함수 코드 안의 this 값이 초기화되는 과정

          • 만약 ()(함수 호출 괄호) 왼편의 (식별자 또는 프로퍼티 접근자)가 레퍼런스 타입일경우, 함수 코드 안의 this 값은 해당 **레퍼런스 타입**의 **base** 속성 값으로 **초기화**된다.<p>

          • 그러나 레퍼런스 타입이 아닌 경우, this 값은 자동으로 null 을 갖게되며, nullthis 값으로 **평가**될 수 없기때문에, **암묵적**으로 **전역 객체**로 **변환**된다.<p>

          • A 함수

              // global Execution Context
            
              function A(){
            
                // function Execution Context
                // this 값은 해당 레퍼런스 타입의 base 속성 값으로 초기화된다.
                console.log(this); // global object
              };
            
              // [호출자].[propertyName](호출괄호)
              this.A(); // this.A();
            
          • 레퍼런스 타입 체크

            
              // reference Type
              var AReference = {
                base: global object,
                propertyName: 'A'
              };
            
              // referenceType 값을 반환한다.
              GetValue(AReference); // A function object
            
            
          • obj 객체의 X 메서드

            
              // global Execution Context
            
              var obj = {
                X: function(){
                  return this;
                }
              };
            
              console.log(obj.X()); // obj Object
              console.log(obj['X']()); // obj Object
            
          • 레퍼런스 타입 체크

            
              // reference Type
              var objXReference = {
                base: obj Object,
                propertyName: 'X'
              };
            
              // referenceType 값을 반환한다.
              GetValue(objXReference); // X function object
            
          • obj 객체의 A 메서드를 x 변수에 할당한다.

            
              // global Execution Context
            
              var obj = {
                A: function(){
                  return this;
                }
              };
            
              // x 변수 선언
              var x = obj.A;
            
              console.log(x()); // global object
            
          • 레퍼런스 타입 체크

            
              // reference Type
              var objAReference = {
                base: obj Object,
                propertyName: 'A'
              };
            
              // reference Type
              var xReference = {
                base: global object,
                propertyName: 'x'
              };
            
              // referenceType 값을 반환한다.
              GetValue(xReference); // A function object
            
          • 레퍼런스 타입이 아닌 함수 표현식(즉시 실행 함수)

              // global Execution Context
            
              // 식별자 또는 프로퍼티 접근자가 아닌 함수 표현식
              (function () {
                // 이 경우 레퍼런스 타입이 존재하지 않으므로, 결국 null 을 반환 후 자동으로 전역 객체로 변환된다.
                console.log(this); // null => global object
              })();
            
          • 레퍼런스 타입 체크

            
              // 식별자 또는 프로퍼티 접근자가 아닌 함수 표현식(즉시 실행 함수)은 reference Type 값이 존재하지 않는다.
            
          • 함수 내부에 선언된 함수

            • A 함수 내부에 선언된 B 함수는 AO(VO) 가 갖는 속성 중 하나이다. 또한 AO(VO) 는 항상 this 값을 null 로 반환하기 때문에, 결국 B 함수 내부 this 는 global object 를 갖게된다.(AO.B() === null.B())<p>

              • The activation object always returns as this value — null (i.e. pseudo-code AO.bar() is equivalent to null.bar()). Here again we come back to the described above case, and again, this value is set to global object.

                ```javascript
                

                // global execution context

                function A() {

                // function Execution Context
                      
                function B() {
                  console.log(this); // this === null => global object
                }
                      
                B(); // AO.B() == null.B()   }
                

                A(); ```

            • ECStack 내부

              ```javascript
                var ECStack = [
                  <B> activeFunctionExecutionContext: {
                    AO(VO): {
                      arguments: {
                      }
                    },
                    this: null ==> global Object                          
                  },                      
                  <A> functionExecutionContext: {
                    AO(VO): {
                      arguments: {
                      }
                      B: < reference to function >
                    },
                    this: global Object                          
                  },
                  globalExecutionContext: {
                    VO: {
                      A: < reference to function >
                    },
                    this: global object                        
                  }
                ];
              ```
              
            • 레퍼런스 타입 체크

              
                  // reference Type
                  var BReference = {
                    base: null,
                    propertyName: 'B'
                  };
              
                  // referenceType 값을 반환한다.
                  GetValue(BReference); // B function object
              
          • 생성자 함수 호출

            • new 연산자의 객체 매커니즘에 따라 this 값은 생성된 객체초기화 된다.

               ```javascript
                      
                 // global Execution Context
                      
                 function A(){
                      
                   // function Execution Context
                      
                   this.id = 'mohwa';
                                  
                   // new 연산자 + 생성자 함수를 통해 생성된 객체로 초기화된다.
                   console.dir(this); // A object
                 }
                                
                 // 객체를 생성한다.
                 new A;
               ```
               ![](https://www.dropbox.com/s/4mkmvx22cmlo7ow/92.jpg?dl=1)
              
            • new 연산자 매커니즘 Pseudo-Code

               ```javascript
               function A(){
                      
                 this.id = 'mohwa';
                      
                 console.dir(this); // A instance
               }
                      
               var o = New(A);
                      
               console.dir(o); // A instance
                      
               // new 연산자 구현
               function New(constructor) {
                      
                 constructor = constructor || function F(){};
                      
                 var o = {};
                      
                 // 전달받은 생성자 함수 객체의 원형을 o 객체의 원형으로 위임한다.
                 o.__proto__ = constructor.prototype;
                      
                 // 생성자 함수 객체의 this 값을 o 객체로 초기화한다.
                 constructor.call(o);
                      
                 return o;
               }
               ```	
               ![](https://www.dropbox.com/s/j4xkyq7ixpdvcbf/93.jpg?dl=1)
              
          • 함수 호출 시 this 값을 초기화 하는 방법

            • Function.prototype 객체 메서드인 callapply 메서드를 통해, 함수 호출 시 this 값을 초기화할 수 있다.<p>

            • call 메서드를 통해 전달된 객체this 값을 초기화한다.

               ```javascript
                              
               function A(x, y){
              
                 // function execution context
              
                 console.dir(this); // obj Object
              
                 console.log(x); // 1
                 console.log(y); // 2
              
               }
              
               var obj = {
                 id: 'mohwa'
               };
              
               // A 함수 객체의 this 값을 obj 객체로 초기화 한다.
               A.call(obj, 1, 2);
               ```
              
            • apply 메서드를 통해 전달된 객체this 값을 초기화한다.

               ```javascript
               function A(x, y){
              
                 console.dir(this); // obj Object
              
                 console.log(x); // 1
                 console.log(y); // 2
               }
              
               var obj = {
                 id: 'mohwa'
               };
              
               // A 함수 객체의 this 값을 obj 객체로 초기화 한다.
               A.apply(obj, [1, 2]);
               ```
              

    참고 URL

    Read more


  • javascript 

    이 글은 오래전 김훈민님의 블로그 글을 통해 ECMA-262-3 in detail 번역본을 정독 후, 개인적인 테스트를 통해 다시한번 정리해본 내용입니다.

    • Execution Context 는 일종의 Call Stack 형태를 취하고 있으며, Stack 의 바닥에는 Global Execution Context 가 존재하고, 가장 상위에는 현재 활성화된 Execution Context 가 놓이게된다.

      • 콜 스택(call stack) 이란 컴퓨터 과학에서 실행할 컴퓨터 프로그램 코드 정보를 저장하는 스택 자료구조이다. 또한 실행 스택(execution stack), 제어 스택 (control stack), 런 타임 스택 (run-time) 스택 혹은 기계 스택 (machine stack) 이라고도 하며 그냥 줄여서 스택 (the stack) 이라고도 한다. 소프트웨어 프로그램의 기능 수행에 있어 콜 스택의 유지 보수가 중요함에도 불구하고 구현 상세는 고급 프로그래밍 언어에서는 보통 감추어지며 자동화되어 있다.
    • ECStackExecution ContextCall Stack 을 의미한다.

    • ECStack 은 여러 종류의 Execution Context 들이 들어오고 나가면서(pushed or poped), 지속적으로 관리(변경)된다.

      • ECStackLIFO(Last In First out) 자료구조를 가진다.
    • 런타임 시점에서 실행 코드를 만나게되면 해당되는 Execution Context 가 생성되고, 생성된 Execution Context 안에서 실행 코드가 처리된다.

      • Execution Context 예 1

        ```javascript
          // global Execution Context(buttom)
          console.log("global Execution Context");
          
          function Func1(){
            // active function Execution Context(top)
          };
          
          function Func2(){
            // function Execution Context
            Func1();
          };
          
          Func2(); // call function object
        ```
        ```javascript
          var ECStack = [
            <Func1> active function Execution Context,
            <Func2> function Execution Context,
            global Execution Context
          ];
        ```
        ``` javascript
          // ECStack [생성 순서]
          1. global Execution Context
          2. <Func2> functional Execution Context
          3. <Func1> active functional Execution Context
          
          // ECStack [소멸 순서]
          1. <Func1> active functional Execution Context
          2. <Func2> functional Execution Context
          3. global Execution Context
        ```
        
      • Execution Context 예 2(재귀 호출)

        ```javascript
          // global Execution Context
          function A(x){
          
            // function Execution Context
          
            // 전달된 함수 매개변수의 갯수
            if (arguments.length > 0) {
          
              console.log(arguments.length); // 1
              // call function object recursively
              arguments.callee();
            }
          };
          
          A(1); // call function object
        ```
        ```javascript
          var ECStack = [
            <A> active function Execution Context - recursively,
            <A> function Execution Context,
            global Execution Context
          ];
        ```
        ``` javascript
          // ECStack [생성 순서]
          1. global Execution Context
          2. <A> functional Execution Context
          3. <A> active function Execution Context - recursively
          
          // ECStack [소멸 순서]
          1. <A> active function Execution Context - recursively
          2. <A> functional Execution Context
          3. global Execution Context
        ```
        
      • Execution Context 예 3(생성자 함수 호출)

        ```javascript
          
        // global Execution Context
        function A(){
          
          // A function Execution Context
        }
          
        console.dir(new A); // create instance
        ```	
        ```javascript
        
          var ECStack = [
            <A> active function Execution Context,
            global Execution Context
          ];
        ```	
        ``` javascript
          // ECStack [생성 순서]
          1. global Execution Context
          2. <A> active function Execution Context
          
          // ECStack [소멸 순서]
          1. <A> active function Execution Context
          2. global Execution Context
        ```
        

    참고 URL

    Read more