ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
Javascript
   ºËÐĸÅÄî


   Éдº@meituan
Knowing why things work the way they work
but, not everything!
½²Ê²Ã´£¿

Prototype Chain
                  Variable Object

         Constructor
                              Closure
   Execution context
                       This
       Scope Chain
{}
          name

              __proto__
gender
°Ú±Õ.³ó²¹²õ°¿·É²Ô±Ê°ù´Ç±è±ð°ù³Ù²â(¡®±ô±ð²Ô²µ³Ù³ó¡¯)

                   []
               length    0
             __proto__




Array prototype          Object prototype

  concat     fn          hasOwnProperty    fn

    ...      ...                ...       ...

 __proto__                   __proto__    null
instanceof
           []

   __proto__

                        var arr = [];
Array prototype
                        assert(arr instanceof Array);
   concat        fn
                        // true
     ...         ...

  __proto__
                        assert(arr instanceof Object);
                        // true
Object prototype
hasOwnProperty    fn

     ...         ...

  __proto__      null
¶ÔÏóÒòºÎ¶øÀ´



Constructor
¹¹ÔìÆ÷ÖÆÔì¹ý³Ì
F = new NativeObject()
F.[[Class]] = "Function"
F.[[Prototype]] = Function.prototype
F.[[Call]] = <reference to function>
F.[[Construct]] = internalConstructor

// if this function is created via new Function
F.[[Scope]] = globalContext.scope
// else
F.[[Scope]] = activeContext.scope;
F.length = countParameters

__objectPrototype = new Object();
__objectPrototype.constructor = F
F.prototype = __objectPrototype

return F
¶ÔÏóÖÆÔì¹ý³Ì
F.[[Construct]](initialParameters):
O = new NativeObject();

O.[[Class]] = "Object";

var __objectPrototype = F.prototype;
// if __objectPrototype is an object
O.[[Prototype]] = __objectPrototype
// else
O.[[Prototype]] = Object.prototype;

R = F.[[Call]](initialParameters); this === O;

// if R is a object
return R
// else
return O
function Engineer(name, gender) {
    this.name = name;
    this.gender = gender;
}

Engineer.prototype.print = function() {
    alert(this.name + this.gender);
}

var shangchun = new Engineer(¡®Éдº¡¯, ¡®male¡¯);
var lizhiye = new Engineer(¡®ÀîÖ¾Òµ¡¯, ¡®male¡¯);
Engineer
                      other properties

                       prototype

   shangchun           __proto__

  name      Éдº

 gender     male

__proto__          Engineer prototype        Function.prototype
                    constructor                   <built-ins>
                       print          fn        __proto__
     lizhiye         __proto__
  name      ÀîÖ¾Òµ

 gender     male

__proto__
                    Object.prototype
                        <built-ins>

                      __proto__       null
´úÂëÀàÐÍ

                eval code
                  10%



                            global code
                                30%

function code
     60%
ÿÖÖ´úÂëÀàÐͶ¼»áÔËÐÐÔÚ×Ô¼ºµÄÉÏÏÂÎÄÖÐ


 Execution Contexts
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1

var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}
                                 First
var bar = foo();              Function EC

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}
                                Second
var bar = foo();              Function EC

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}
                               Eval EC
var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}
                                 Third
var bar = foo();              Function EC

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1                   Global EC
var res = eval('{ x: 1 }');

bar(); // 1
function foo() {
    var x = 1;
    return function () {
        alert(x);
                              EC Stack
    };
}

var bar = foo();

bar(); // 1

var res = eval('{ x: 1 }');

bar(); // 1
Ïê½â·¡°ä

        Execution Context
                   {
                        vars,
Variable Object         function declarations,
                        arguments...
                   }

                       [Variable object + all
  Scope Chain
                           parent scopes]

   thisValue               Context object
Variable Object

// Global EC
Variable Object === this === global object


// Function EC
Variable Object === Activation Object

AO === Abstract VO +
       arguments object +
       formal parameters
Global VO

var bar = 10;
                            Global VO
function foo() {
    var x = 1;             bar      10
    return function () {   foo      fn
        alert(x);
    };                      built-ins
}
Activation Object

function foo(x, y) {                   AO
    var z = 30;
    // FD                        x          10
    function bar() {}            y          20
    // FE
    (function baz() {})();   arguments {0:10, 1:20}
}
                                 z          30
foo(10, 20);                    bar         fn
´úÂëÖ´Ðйý³Ì


1. ½øÈëÖ´ÐÐÉÏÏÂÎÄ
 1.1. ³õʼ»¯±äÁ¿¶ÔÏó(Variable Object)
 1.2. ³õʼ»¯×÷ÓÃÓòÁ´(Scope Chain)
 1.3. ³õʼ»¯this
2. Ö´ÐдúÂë
³õʼ»¯VO

1. ÈôΪFunction EC£¬½«º¯Êý¸÷¸öÐβÎÃûÉèΪVOÊô
  ÐÔ£¬ÊôÐÔֵΪÐβδ«Öµ»òundefined


2. ½«¸÷¸öº¯ÊýÉùÃ÷ÉùÃ÷µÄº¯ÊýÃûÉèΪVOÊôÐÔ£¬ÆäֵΪ
   ¶ÔÓ¦µÄº¯Êý¶ÔÏó¡£ÖØÃûÔò¸²¸Ç


3. ½«¸÷¸ö±äÁ¿ÉùÃ÷ÉùÃ÷µÄ±äÁ¿ÉèΪVOÊôÐÔ£¬ÆäֵΪ
   undefined¡£½öÔÚÓëÆäËü±äÁ¿ÖØÃûʱ¿É¸²¸Ç
function foo(x, y) {
    alert(x) // 1
    var x = 10;
    alert(x) // 10

    alert(y) // function
    function y() {};
}

foo(1, 2);
bar VO
                                  z         30

                              __parent__


var x = 10;
                                bar.[[Scope]]
(function foo() {
    var y = 20;
                                  foo VO
                                  y         20
       (function bar() {      __parent__
           var z = 30;
       })();
                                Global VO
})()
                                  x         10
                              other properties
                              __parent__   null


                           bar context scope chain
¶ÔÓÚ×÷ÓÃÓòÁ´



1. ¾²Ì¬×÷ÓÃÓò(lexical scope)
2. ÔÚÖ´ÐдúÂë½×¶Î¿ÉÒÔ±»catch¡¢with¸Ä±ä
3. Ϊ±Õ°üµÄʵÏÖÌṩÁË»ù´¡
Closure


º¯ÊýÊÇ?Ò»¼¶¶ÔÏó
             ÿ¸öº¯Êý¶¼ÊÇ?Ò»¸ö±Õ°ü
 ×÷ÓÃÓòÁ´
function foo() {
    var x = 10;
    return function () {
        alert(x);
    };
}

var x = 20;

var returnedFunction = foo();

returnedFunction();
                      10
var x = 10;

function foo() {
    alert(x);
}

(function(funArg) {
    var x = 20;

    var returnedFunction = funArg;

    returnedFunction();
})(foo);
                          10
This

1. Global EC:
      this === global object === global VO


2. Function EC:
  2.1. ×÷Ϊº¯Êýµ÷ÓÃʱ£¬this === global object

  2.2. ×÷Ϊ·½·¨µ÷ÓÃʱ£¬this === caller object

  2.3. ×÷Ϊ¹¹ÔìÆ÷µ÷ÓÃʱ£¬this === new object

  2.4. ͨ¹ýcall/applyµ÷ÓÃʱ£¬this === first argument
²Î¿¼


? The Core Dmitry Soshnikov
? ECMA-262-3 in detail Dmitry Soshnikov
? Annotated ECMAScript 5.1 es5.github.com
Thanks

More Related Content

The core of javascript

  • 1. Javascript ºËÐĸÅÄî Éдº@meituan
  • 2. Knowing why things work the way they work
  • 4. ½²Ê²Ã´£¿ Prototype Chain Variable Object Constructor Closure Execution context This Scope Chain
  • 5. {} name __proto__ gender
  • 6. °Ú±Õ.³ó²¹²õ°¿·É²Ô±Ê°ù´Ç±è±ð°ù³Ù²â(¡®±ô±ð²Ô²µ³Ù³ó¡¯) [] length 0 __proto__ Array prototype Object prototype concat fn hasOwnProperty fn ... ... ... ... __proto__ __proto__ null
  • 7. instanceof [] __proto__ var arr = []; Array prototype assert(arr instanceof Array); concat fn // true ... ... __proto__ assert(arr instanceof Object); // true Object prototype hasOwnProperty fn ... ... __proto__ null
  • 9. ¹¹ÔìÆ÷ÖÆÔì¹ý³Ì F = new NativeObject() F.[[Class]] = "Function" F.[[Prototype]] = Function.prototype F.[[Call]] = <reference to function> F.[[Construct]] = internalConstructor // if this function is created via new Function F.[[Scope]] = globalContext.scope // else F.[[Scope]] = activeContext.scope; F.length = countParameters __objectPrototype = new Object(); __objectPrototype.constructor = F F.prototype = __objectPrototype return F
  • 10. ¶ÔÏóÖÆÔì¹ý³Ì F.[[Construct]](initialParameters): O = new NativeObject(); O.[[Class]] = "Object"; var __objectPrototype = F.prototype; // if __objectPrototype is an object O.[[Prototype]] = __objectPrototype // else O.[[Prototype]] = Object.prototype; R = F.[[Call]](initialParameters); this === O; // if R is a object return R // else return O
  • 11. function Engineer(name, gender) { this.name = name; this.gender = gender; } Engineer.prototype.print = function() { alert(this.name + this.gender); } var shangchun = new Engineer(¡®Éдº¡¯, ¡®male¡¯); var lizhiye = new Engineer(¡®ÀîÖ¾Òµ¡¯, ¡®male¡¯);
  • 12. Engineer other properties prototype shangchun __proto__ name Éдº gender male __proto__ Engineer prototype Function.prototype constructor <built-ins> print fn __proto__ lizhiye __proto__ name ÀîÖ¾Òµ gender male __proto__ Object.prototype <built-ins> __proto__ null
  • 13. ´úÂëÀàÐÍ eval code 10% global code 30% function code 60%
  • 15. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 var res = eval('{ x: 1 }'); bar(); // 1
  • 16. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 17. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 18. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 19. function foo() { var x = 1; return function () { alert(x); EC Stack }; } First var bar = foo(); Function EC bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 20. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 21. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 22. function foo() { var x = 1; return function () { alert(x); EC Stack }; } Second var bar = foo(); Function EC bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 23. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 24. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 25. function foo() { var x = 1; return function () { alert(x); EC Stack }; } Eval EC var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 26. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 27. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 28. function foo() { var x = 1; return function () { alert(x); EC Stack }; } Third var bar = foo(); Function EC bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 29. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 30. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 Global EC var res = eval('{ x: 1 }'); bar(); // 1
  • 31. function foo() { var x = 1; return function () { alert(x); EC Stack }; } var bar = foo(); bar(); // 1 var res = eval('{ x: 1 }'); bar(); // 1
  • 32. Ïê½â·¡°ä Execution Context { vars, Variable Object function declarations, arguments... } [Variable object + all Scope Chain parent scopes] thisValue Context object
  • 33. Variable Object // Global EC Variable Object === this === global object // Function EC Variable Object === Activation Object AO === Abstract VO + arguments object + formal parameters
  • 34. Global VO var bar = 10; Global VO function foo() { var x = 1; bar 10 return function () { foo fn alert(x); }; built-ins }
  • 35. Activation Object function foo(x, y) { AO var z = 30; // FD x 10 function bar() {} y 20 // FE (function baz() {})(); arguments {0:10, 1:20} } z 30 foo(10, 20); bar fn
  • 36. ´úÂëÖ´Ðйý³Ì 1. ½øÈëÖ´ÐÐÉÏÏÂÎÄ 1.1. ³õʼ»¯±äÁ¿¶ÔÏó(Variable Object) 1.2. ³õʼ»¯×÷ÓÃÓòÁ´(Scope Chain) 1.3. ³õʼ»¯this 2. Ö´ÐдúÂë
  • 37. ³õʼ»¯VO 1. ÈôΪFunction EC£¬½«º¯Êý¸÷¸öÐβÎÃûÉèΪVOÊô ÐÔ£¬ÊôÐÔֵΪÐβδ«Öµ»òundefined 2. ½«¸÷¸öº¯ÊýÉùÃ÷ÉùÃ÷µÄº¯ÊýÃûÉèΪVOÊôÐÔ£¬ÆäֵΪ ¶ÔÓ¦µÄº¯Êý¶ÔÏó¡£ÖØÃûÔò¸²¸Ç 3. ½«¸÷¸ö±äÁ¿ÉùÃ÷ÉùÃ÷µÄ±äÁ¿ÉèΪVOÊôÐÔ£¬ÆäֵΪ undefined¡£½öÔÚÓëÆäËü±äÁ¿ÖØÃûʱ¿É¸²¸Ç
  • 38. function foo(x, y) { alert(x) // 1 var x = 10; alert(x) // 10 alert(y) // function function y() {}; } foo(1, 2);
  • 39. bar VO z 30 __parent__ var x = 10; bar.[[Scope]] (function foo() { var y = 20; foo VO y 20 (function bar() { __parent__ var z = 30; })(); Global VO })() x 10 other properties __parent__ null bar context scope chain
  • 40. ¶ÔÓÚ×÷ÓÃÓòÁ´ 1. ¾²Ì¬×÷ÓÃÓò(lexical scope) 2. ÔÚÖ´ÐдúÂë½×¶Î¿ÉÒÔ±»catch¡¢with¸Ä±ä 3. Ϊ±Õ°üµÄʵÏÖÌṩÁË»ù´¡
  • 41. Closure º¯ÊýÊÇ?Ò»¼¶¶ÔÏó ÿ¸öº¯Êý¶¼ÊÇ?Ò»¸ö±Õ°ü ×÷ÓÃÓòÁ´
  • 42. function foo() { var x = 10; return function () { alert(x); }; } var x = 20; var returnedFunction = foo(); returnedFunction(); 10
  • 43. var x = 10; function foo() { alert(x); } (function(funArg) { var x = 20; var returnedFunction = funArg; returnedFunction(); })(foo); 10
  • 44. This 1. Global EC: this === global object === global VO 2. Function EC: 2.1. ×÷Ϊº¯Êýµ÷ÓÃʱ£¬this === global object 2.2. ×÷Ϊ·½·¨µ÷ÓÃʱ£¬this === caller object 2.3. ×÷Ϊ¹¹ÔìÆ÷µ÷ÓÃʱ£¬this === new object 2.4. ͨ¹ýcall/applyµ÷ÓÃʱ£¬this === first argument
  • 45. ²Î¿¼ ? The Core Dmitry Soshnikov ? ECMA-262-3 in detail Dmitry Soshnikov ? Annotated ECMAScript 5.1 es5.github.com