Lexical environment in ecma 262 5

1,500 views
1,401 views

Published on

Lexical environment in ecma 262 5

  1. 1. By 김훈민 NHN Technology Services Corp. Front-End Development Team http://huns.me Lexical Environment in ECMA-262 Edition 5.1
  2. 2. ECMA-262 Edition 5, 2009 ECMA-262 Edition 3 탄생 이후 10년
  3. 3. JSON Function Object Arrays use strict Date New Features in ECMA-262 Edition 5
  4. 4. 1 more thing.
  5. 5. I will note that there are some real improvements in ES5, in particular to Chapter 10 which now uses declarative binding environments. ES1-3's abuse of objects for scopes (again I'm to blame for doing so in JS in 1995, economizing on objects needed to implement the language in a big hurry) was a bug, not a feature. https://mail.mozilla.org/pipermail/es-discuss/2010-April/010915.html
  6. 6. Before ECMA 262-5…? Variable Object
  7. 7. Chapter 10. Execution Context ECMAScript 코드를 실행하는 환경
  8. 8. Execution Context <script> var sayHello = "Hello"; function person(){ var first = 'David'; function getFirstName(){ eval("first = 'Steven'"); return first; } alert(sayHello + getFirstName()); } person(); </script> Execution Context
  9. 9. Execution Context Stack Execution Context Execution Context Execution Context Execution Context
  10. 10. Executable Code <script> var sayHello = "Hello"; function person(){ var first = 'David'; function getFirstName(){ eval("first = 'Steven'"); return first; } alert(sayHello + getFirstName()); } person(); </script> Function Code Global Code Eval Code Evaluating Initializing execution context Initializing execution context Initializing execution context
  11. 11. Pseudo code ExecutionContext = { LexicalEnvironment : [Lexical Environment], VariableEnvironment : [Lexical Environment], ThisBinding : [object] } * […]은 Value Type
  12. 12. Lexical Environment 자원을 어디에서 찾을 것인가
  13. 13. Components of Lexical Environment lexical environment = { environment record : -, outer environment reference : - } 지역 식별자 덩어리 유효범위 내의 식별자를 바인딩 중첩 유효범위를 가질 수 있는 환경에 서 상위 lexical environment를 참조
  14. 14. 2 type of environment record Declarative vs Object
  15. 15. DeclarativeEnvironmentRecord : { x : 10, y : 20, result : 30 }
  16. 16. ObjectEnvironmentRecord : { bindObject : globalObject }
  17. 17. Establishing an Execution Context 실행 콘텍스트 초기화 thisBinding, Hoisting
  18. 18. Global Code { LexicalEnvironment : globalEnv, VariableEnvironment : globalEnv, ThisBinding : window } Global Execution Context ObjectEnvironmentRecord : { bindingObject : window }, OuterEnvironmentReferece : null, globalEnv
  19. 19. function sum(x, y){ var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); Global Execution Context sum’s Execution Context Function Code
  20. 20. thisBinding sunFunctionEC.thisBinding = null; function sum(x, y){ var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); { ThisBinding : null, } sumFunctionEC
  21. 21. thisBinding sunFunctionEC.thisBinding = null; function sum(x, y){ var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); { ThisBinding : null, } sumFunctionEC ThisBinding이 null, undefined인 경우 this = global “use strict” 모드에서는 this = null
  22. 22. thisBinding on Function sunFunctionEC.ThisBinding = foo;foo.sum(10, 20); { ThisBinding : foo, } sumFunctionEC
  23. 23. { ThisBinding : null, LexicalEnv : - } sumFunctionEC EnvironmentRecord : {} localEnv localEnv Creating local lexical environment
  24. 24. Declaration Binding Instantiation 실행 콘텍스트 바인딩 초기화
  25. 25. function sum(x, y){ console.log(barr); var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); { ThisBinding : null, LexicalEnv : localEnv } sumFunctionEC EnvironmentRecord : { } x : 10, y : 20, localEnv Declaration Binding Instantiation
  26. 26. EnvironmentRecord : { x : 10, y : 20, } function sum(x, y){ console.log(barr); var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); printResult : Function Reference Hoisting { ThisBinding : null, LexicalEnv : localEnv } sumFunctionEC localEnv Declaration Binding Instantiation
  27. 27. function sum(x, y){ console.log(barr); var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); EnvironmentRecord : { x : 10, y : 20, printResult : Function Reference, } arguments : Arguments Object { ThisBinding : null, LexicalEnv : localEnv } sumFunctionEC localEnv Declaration Binding Instantiation
  28. 28. EnvironmentRecord : { x : 10, y : 20, printResult : Function Reference } function sum(x, y){ console.log(barr); var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); result : undefined, barr : undefined Hoisting { ThisBinding : null, LexicalEnv : localEnv } sumFunctionEC localEnv Declaration Binding Instantiation
  29. 29. EnvironmentRecord : { x : 10, y : 20, printResult : Function Reference, result : undefined, barr : undefined } function sum(x, y){ console.log(barr); var result = x + y; var barr = function(){ console.log("barr"); } function printResult(){ console.log(result); } return printResult; } sum(10, 20); { ThisBinding : null, LexicalEnv : localEnv } sumFunctionEC localEnv Declaration Binding Instantiation
  30. 30. function sum(x, y){ console.log(barr); var result = x + y; var barr = function(){ console.log("barr"); } function foo(){ console.log("foo"); } return result; } sum(10, 20); result : 30, barr : Function Reference { ThisBinding : null, LexicalEnv : localEnv } sumFunctionEC EnvironmentRecord : { x : 10, y : 20, foo : Function Reference result : undefined, barr : undefined } localEnv Declaration Binding Instantiation result : 30, barr : Function Reference
  31. 31. Identifier Resolution 식별자와 묶여있는 값을 찾아가는 과정 스코프 체인의 원리
  32. 32. outer environment reference The outer environment reference is used to model the logical nesting of Lexical Environment values
  33. 33. var a = 10; (function foo() { var b = 20; (function bar() { var c = 30; console.log( a + b + c ); })(); })(); Identifier Resolution #1 Global Execution Context foo’s Execution Context bar’s Execution Context
  34. 34. var a = 10; (function foo() { var b = 20; (function bar() { var c = 30; console.log( a + b + c ); })(); })(); LexicalEnvironment : { EnvironmentRecord : { c : 30 } OuterEnvironmentReference : fooEC.LexicalEnvironment }, bar’s EC LexicalEnvironment : { EnvironmentRecord : { b : 20 } OuterEnvironmentReference : globalEC.LexicalEnvironment }, foo’s EC LexicalEnvironment : { EnvironmentRecord : { a : 10 } OuterEnvironmentReference : null }, Global EC Identifier Resolution #1
  35. 35. var a = 10; (function foo() { var b = 20; (function bar() { var c = 30; console.log( a + b + c ); })(); })(); LexicalEnvironment : { EnvironmentRecord : { c : 30 } OuterEnvironmentReference : fooEC.LexicalEnvironment }, barEC LexicalEnvironment : { EnvironmentRecord : { b : 20 } OuterEnvironmentReference : globalEC.LexicalEnvironment }, fooEC LexicalEnvironment : { EnvironmentRecord : { a : 10 } OuterEnvironmentReference : null }, globalEC Identifier Resolution #2
  36. 36. Closure 자유변수를 간직한 코드 블럭
  37. 37. A lexical environment that defines the environment in which a Function object is executed. Function Object’s Internal property [[Scope]]
  38. 38. function sum(x, y){ var result = x + y; function printResult(){ console.log("foo:”+ result); } return printResult; } var print = sum(10, 20); print(); LexicalEnvironment = { EnvironmentRecord : { x : 10, y : 20, result : undefined, printResult : function }, OuterEnvironmentReference : globalEC.lexicalEnvironment }, ThisBinding : null sum’s EC [[Scope]]: printResult function sumEC’s lexical environment Creating Function Object
  39. 39. function sum(x, y){ var result = x + y; function printResult(){ console.log("foo:”+ result); } return printResult; } var print = sum(10, 20); print(); [[Scope]]: printResult function sumEC’s lexical environment ThisBinding : null sum’s EC LexicalEnvironment = { EnvironmentRecord : { x : 10, y : 20, result : undefined, printResult : function }, OuterEnvironmentReference : globalEC.lexicalEnvironment }, Closure
  40. 40. function sum(x, y){ var result = x + y; function printResult(){ console.log("foo:”+ result); } return printResult; } var print = sum(10, 20); print(); [[Scope]]: printResult function sumEC’s lexical environment LexicalEnvironment = { EnvironmentRecord : { x : 10, y : 20, result : undefined, printResult : function }, OuterEnvironmentReference : globalEC.lexicalEnvironment }, Closure
  41. 41. [[Scope]]: sumEC’s lexical environment printResult function Creating printResult’s EC LexicalEnvironment = { EnvironmentRecord : { … }, OuterEnvironmentReference : sumEC’s lexical environment }, ThisBinding : null printResult’s ECfunction sum(x, y){ var result = x + y; function printResult(){ console.log("foo:”+ result); } return printResult; } var print = sum(10, 20); print();
  42. 42. VariableEnvironment LexicalEnvironment의 쌍둥이
  43. 43. Execution Context Pseudo code ExecutionContext = { LexicalEnvironment : [lexical environment], VariableEnvironment : [lexical environment], ThisBinding : [object] } * […]은 type
  44. 44. LexicalEnvironment and VariableEnvironment components of an execution context are always Lexical Environments - 10.3 Execution Contexts in ECMA 262-5 -
  45. 45. VariableEnvironment = LexicalEnvironment { ThisBinding : null, LexicalEnv : globalEnv, VariableEnv : null } Global EC EnvironmentRecord : { bindingObject : window }, OuterEnviromentReferece : null globalEnv var foo = "abc"; with({ foo : "bar" }) { function f() { console.log(foo); } f(); } GlobalEC.VariableEnv = GlobalEC.LexicalEnv; globalEnv
  46. 46. The value of the VariableEnvironment component never changes while the value of the LexicalEnvironment component may change during execution of code within an execution context. - 10.3 Execution Contexts in ECMA 262-5 -
  47. 47. With Statement #1 { ThisBinding : null, LexicalEnv : globalEnv, VariableEnv : globalEnv } Global EC EnvironmentRecord : { bindingObject : window }, OuterEnviromentReferece : null globalEnv var foo = "abc"; with({ foo : "bar" }) { function f() { console.log(foo); } f(); } ObjectEnvironmentRecord : { bindingObject : - }, OuterEnviromentReferece : newEnv {foo:bar} newEnv, GlobalEC.LexicalEnv
  48. 48. With Statement #2 { ThisBinding : null, LexicalEnv : newEnv, VariableEnv : globalEnv } Global EC EnvironmentRecord : { bindingObject : window }, OuterEnviromentReferece : null globalEnv var foo = "abc"; with({ foo : "bar" }) { function f() { console.log(foo); } f(); } ObjectEnvironmentRecord : { bindingObject : { foo : bar } }, OuterEnviromentReferece : GlobalEC.LexicalEnv newEnv
  49. 49. With Statement #3 { ThisBinding : null, LexicalEnv : newEnv, VariableEnv : globalEnv } Global EC EnvironmentRecord : { bindingObject : window }, OuterEnviromentReferece : null globalEnv ObjectEnvironmentRecord : { bindingObject : { foo : bar } }, OuterEnviromentReferece : null newEnv globalEnv with문이 끝나면 GlobalEC.LexicalEnv = GlobalEC.VariableEnv;
  50. 50. Reference 1. ECMAScript Language Specification 5.1 Edition 2. ECMAScript 5 spec: LexicalEnvironment versus VariableEnvironment 3. ECMA-262-5 in detail. Chapter 3.2 Lexical environments
  51. 51. Thanks. email : kim.hunmin@nhn.com facebook : facebook.com/jeokrang blog : http://huns.me

×