드미트리 소스니코브의 JavaScript Core에 대한 내용을 간략히 요약해 보자.
▶ 오브젝트 (객체, An Object)
- 오브젝트는 한개의 프로토타입 오브젝트를 가지고 있으면서 프로퍼티들의 집합이다.
- 오브젝트의 프로토타입은 내부 [[Prototype]] 프로퍼티에 의해 참조된다.
- [[Prototype]] 보다는 __<internal-property>__ 를 사용하나, 특별히 프로토타입 오브젝트는 __proto__ 프로퍼티 변수로 표시한다.
예)
var foo={
x: 10,
y: 20
}
해당 객체에는 3개의 프로퍼티가 존재하게 된다.
▶ 프로토타입 체인
- 프로토타입 체인은 상속/공유되는 프로퍼티들의 구현에 사용되는 객체들의 유한 연결이다.
- ECMAScript는 자바와 같은 일반적인 class-based 상속이 아니라 prototype chain을 통하여 상속은 한다. 이를 위임형 상속(delegation based inheritance) 또는 프로토타입형 상속(prototype based inheritance)이라 한다.
- 이는 ECMAScript에는 class라는 개념이 없기 때문이다. 속성(프로퍼티)/메소드등을 동적으로 할당할 수 있기 때문에 class정의 자체가 필요없음
- 예로 b, c의 공통영역에 a 객체를 저장하면, b, c는 자신에게 추가적인 프로퍼티와 메소드를 저장할 수 있는 것이다.
- b가 calculate 메소드를 찾아가는 방법 : b 객체안에 메소드가 없을 경우, prototype chain을 거쳐서 찾는다. 메소드를 찾는다. 찾지 못할 경우 undefined 값이 리턴된다. (최상위 오브젝트 Object.prototype 값은 null 이다.)
- 주의 할것중 상속하여 사용시 this는 원래 객체를 가르킨다.
- 예로 this가 가르키는 객체로 this.y 는 b, c 객체이고, this.x는 a 객체를 가르킨다.
▶ 생성자 (Constructor)
- 생성자를 통해 객체를 생성시 유용한 것들이 있다.
생성자를 사용하면 펑션의 prototype 프로퍼티가 <생성자 함수명칭>.prototype 객체를 가르킨다. (그림 3.A)
예로 constructor function을 사용하여 b, c에 생성한 객체의 주소를 할당하면 b, c의 __proto__는 Foo.prototype 객체를 참조하게 된다. Foo.prototype 객체의 constructor는 원형의 constructor function 인 Foo를 가르키게 된다.
* 참조 : 자바스크립트의 new 의미 (http://zero.diebuster.com/zero/?p=36)
그림으로 그리면 다음과 같다
- Foo 자신의 __proto__는 Function.prototype 을 갖는다.
- Foo.prototype 오브젝트의 constructor는 자동 생성되어 Foo를 참조한다
- Foo.prototype은 b, c 오브젝트의 prototype에 참조되는 Foo의 프로퍼티이다. (프로퍼티에 .x .calculate가 붙으면서 별도 객체가 되었다)
▶ Execution Context Stack
- runtime program execution에 대해서 알려면 ECMAScript의 실행컨텍스트스택의 동작방식을 알아야 한다
- 3가지 타입 존재 : global code, function code, eval code
- 3가지 code는 execution context 인스턴스안에서 검증되어 진다.
- global context는 1개만 있고, function과 eval execution context들이 여러개 있게 된다. 만일 function이 호출되면 function execution context안으로 들어가 function code가 검증되어 진다. eval function은 특별히 eval execution context안에 들어서 eval code를 검증한다.
- Execution Context(EC)는 Stack에 담겨서 EC1 -> EC2 로 호출할 때마다 자기자신은 caller와 callee가 되어 코드 끝까지 수행이 되는 것이다.
글로벌 EC가 최소 caller가 되어 다음 foo(10) EC callee를 활성화 하고, foo(10) EC가 caller 되어 foo(20) EC callee를 활성화 하는 식으로 옮겨가는 구조를 Stack안에 구현되어 수행되는 것이다. 이른 execution context stack이라 한다.
- ECMAScript의 코드 동작방식에서 Global EC는 하나가 생성되어 있고, 펑션 EC는 Stack이 넣어져서 수행되고 완료되면 다시 Stack에서 빠지게 된다.
- 모든 EC를 Object로 간주되고, EC안의 code를 수행하는 주체가 된다.
▶ Execution Context
- EC는 context상태를 저장하기 위한 프로퍼티와 관련 코드 수행 경로 추적을 위한 프로퍼티등을 가지고 있는 단순 객체(오브젝트)이다.
- Variable Object (VO)는 EC와 관련된 scope of data 이다. (A variable object is a scope of data related with the execution context.)
- 변수(variable)과 펑션선언(function declaration)을 저장한다. function expression은 저장하지 않는다.
baz는 function expression이어서 Global Variable Object 에 저장되지 않는다.
- Activation Object (AO)는 Function context에서의 Variable Object이다.
- caller에 의해 function context가 활성화 되면 activation object가 생성되고 function이 호출된다.
- 호출시에 arguments객체-indexed map-에 파라미터 값를 담아서 넘겨준다.
- activation object도 variable object이므로 variable, function declaration, 일반 파라미터, arguments 객체를 저장한다.
▶ Scope Chain
- 스코프 체인은 컨텍스트의 코드를 표현하는 식별자(identifiers)를 찾기위한 오브젝트 목록이다. (A scope chain is a list of objects that are searched for identifiers appear in the code of the context)
- 규칙인 prototype chain과 동일하다.
- 즉, 자신의 스코프에서 variable/activation object를 못찾으면 부모의 VO/AO를 찾는다.
- 스코프 체인은 일반적으로 부모 VO들의 목록(list)이다.
- context입장에서 식별자는 variable, function declaration, formal parameter들의 명칭이다.
- scope chain은 __parent__ 내장 프로퍼티로 연결된다. 또는 [[Scope]]로 나타내기도 한다.
이를 통해서 내부의 펑션이 외부의 변수 값을 참조할 수 있게 된다.
반대로 만일 내부 펑션이 외부로 리턴되어 부모가 해당 펑션을 활성화하여 VO를 사용한다면 어떻게 될까? 요건 Closure 에서...
▶ Closure
- ECMAScript에서 펑션은 일급 객체이다. (function is the first-class object)
- 이말은 function을 다른 function에 argument로 전달 할수 있다는 것이다. - funargs- functional arguments라고 함
- 또한 function을 리턴 할 수도 있다. functional value 라고 한다.
- funarg 문제는 closure 개념으로 풀어간다.
- Closure는 좀 더 상세하게 다른 쳅터에서 다룬다.
▶ This
- This 값은 execution context와 관련을 맺는 특별한 오브젝트이다. 그래서 context object라고 불릴 수도 있다.
- 즉, an object which context the execution context is activated.
- this 값은 execution context의 프로퍼티이지 VO의 프로퍼티가 아니다. ( a this value is a property of the execution context, but not a property of the variable object.). 즉, this는 scope chain에 참여하지 않는다. look up 대상이 아니라는 것이다.
- this 값은 caller에 의하여 제공받는다. 즉 EC1 -> EC2를 호출할때 EC1이 caller가 도고 EC2안에 this가 있다면 EC1의 오브젝트가 되는 것이다.
- 좀 더 자세한 사항은 다른 쳅터에서 다룬다.