Сила javascript. 68 Способов Эффективного Использования js

288

Upload: cristina-semeniuc

Post on 24-Nov-2015

231 views

Category:

Documents


11 download

TRANSCRIPT

  • 32.988.02-018.1 004.43 39

    .39 JavaScript. 68 JS.

    .: , 2013. 288 .: . ( -).

    ISBN 978-5-496-00524-1

    - JavaScript -. - , - , JavaScript .

    68 JavaScript, . , - , -, JavaScript.

    12+ ( 12 . 29 2010 . 436-.)

    32.988.02-018.1 004.43

    Addison-Wesley Longman. . - ., , , - . , , - , .

    ISBN 978-0321812186 .ISBN 978-5-496-00524-1 Pearson Education, Inc. , 2013 , , 2013

  • 5

    . . . . . . . . . . . . . . . . . . . . . . . . . . .9

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12JavaScript ECMAScript . .. .. .. .. .. .. .. .. .. .. .. .. .. .. 13- . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 13 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 14

    . . . . . . . . . . . . . . . . . . . . . . . . . 15

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    1. JavaScript . . . . . . . . . . . . . . . . . . . . . .19

    1. , JavaScript . .. .. 202. .. .. .. .. .. .. .. .. .. 283. .. .. .. .. 324. ,

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 405. ==

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 426.

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 467.

    16- . .. .. .. .. .. .. .. 55

  • 6

    2. . . . . . . . . .618.

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 619. . .. .. .. .. .. .. .. .. .. 6510. with .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 6711. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 7212. .. .. .. .. .. .. .. .. .. .. .. .. 7613.

    - .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 79

    14. , - .. .. .. .. .. .. .. .. .. .. .. .. .. 83

    15. , - .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 88

    16. eval . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 91

    17. eval .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 93

    3. . . . . . . . . . . . . . .9618. ,

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 9619.

    . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .10020. call

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .10521. apply

    .. .. .. .. .. .. .. .. .. .. .. .. .. .10722. arguments

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .11023. arguments . .. .. .11224.

    arguments . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .11525. bind

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .11726. bind . .. .12027.

    , .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .122

  • 7

    28. toString . .. .. .12429.

    . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .127

    4. . . . . . . . . . . . . . . . 13030.

    prototype, getPrototypeOf __proto__ .. .. .. .. .. .. .. .. .. .. .. .13131.

    Object.getPrototypeOf, __proto__ . .. .. .. .. .. .13532. __proto__ . .. .13633. ,

    new .. .. .. .. .. .. .. .13834. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .14235.

    . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .14436.

    - .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .14737. this.. .. .. .. .. .. .. .. .. .15038.

    . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .15439. .. .15940. .. .. .. .. .16141. .. .. .. .. .. .. .. .16442.

    . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .166

    5. . . . . . . . . . . . . . . . . . 16943.

    . .. .. .. .. .. .. .16944. null

    .. .. .. .. .17345. hasOwnProperty

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .17646. ,

    .. .. .. .. .. .. .18247.

    Object.prototype .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .18648. 18849.

    for, for...in . .. .194

  • 8

    50. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .196

    51. Array , . .. .202

    52. , Array .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .205

    6. API . . . . . . . . . . . 20753. .. .. .. .. .. .. .. .20754. undefined . .21055. , ,

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .21656. .. .. .. .. .. .. .. .. .22257.

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .22658. . .. .. .. .. .. .. .. .. .. .. .23259. . .. .. .23760. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .242

    7. . . . . . . . . . . . . . . . . . . . . . 24661. - . .. .. .24762.

    . .. .. .. .. .. .. .. .. .. .. .. .. .252

    63. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .257

    64. .. .. .. .. .26265. . .. .. .. .. .26766.

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .27267.

    . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .27868.

    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .282

  • 9

    , JavaScript 1995 , , - Java, , , Netscape , .

    , - ( , -), , , JavaScript - . , , , , - . , , , - , , JavaScript .

    , , - . - (,

  • 10

    ). (monkey-patching), , ( , - spackle).

    , , , JavaScript, - . - , : Prototype Ruby, MochiKit Python, Dojo Java, TIBET Smalltalk. JavaScript - jQuery (JavaScript ), , 2007 , . - - JavaScript-, , .

    JavaScript , , , -.

    JavaScript - ( ) , , , - ECMAScript - , , ,

  • 11

    . JavaScript . - , JavaScript . , ( ), , .

    , , JavaScript - (, !). , , - , JavaScript- , - . , , , , , .

    - , - . , - , JavaScript-, - . , , - .

    , 2006 , Mozilla - - Ecma. , , . !

    (Brendan Eich)

  • 12

    , , , , . , , , . - , , , JavaScript.

    JavaScript. - , , JavaScript . , - JavaScript, (Douglas Crockford), JavaScript: The Good Parts (Marijn Haverbeke) Eloquent JavaScript. - , JavaScript , .

  • 13

    -

    JavaScript EcMaScript

    - . , JavaScript. , , , - ECMAScript. , : - , Ecma International, JavaScript. , ECMA (European Computer Manufacturers Association) Ecma International, , - (ECMAScript), .

    , ECMAScript, , Ecma. , JavaScript - , , , - -. . ECMAScript, JavaScript. - ES5 ECMAScript.

    -

    JavaScript, --. JavaScript - ,

  • 14

    - , . , , Node.js, JavaScript - . -, JavaScript, -. , - , , , API- - -.

    JavaScript , . , ECMAScript JavaScript- . 7, - JavaScript - . JavaScript- -. JavaScript, . , JavaScript ECMAScript.

  • 15

    - JavaScript (Brendan Eich). - JavaScript Mozilla.

    , , - -. (Ben) cowboy (Alman), (Erik Arvidsson), (Mathias Bynens), (Tim) creationix (Caswell), (Michaeljohn) inimino (Clement), (Angus Croll), (Andrew Dupont), (Ariya Hidayat), (Steven Levithan), (Pan Thomakos), (Jeff Walden) (Juriy) kangax (Zaytsev). , ECMAScript, , - Edition5, - - (Allen Wirfs-Brock). Mozilla Developer Network API- .

    . (John Resig) , , .

  • 16

    (Blake Kaplan) (Patrick Walton) - . (Brian Anderson), (Norbert Lindenberg), - (Sam Tobin-Hochstadt), (Rick Waldron) (Patrick Walton).

    - Pearson. (Olivia Basegio), (Audrey Doyle), (Trina MacDonald), (Scott Meyers) (Chris Zahn) , . .

    , - -. , (Erik Arvidsson), (Rebecca Murphey), (Rick Waldron) (Richard Worth), . .

    -, . . , , (Andy Denmark), (Rick Waldron) (Travis Winfrey) .

    Java Beach -. . - .

    , . , . (, .)

  • 17

    2006, .

    . , - , , , . , , .

    , , , (Lisa Silveria), .

  • 18

    Mozilla Research. - , , - ( ) - . Ecma TC39, , - JavaScript.

  • 19

    1.

    JavaScript

    JavaScript . , Java, , ( , , -), JavaScript , - . - , , .

    JavaScript - , - . JavaScript, .

  • 1 . JavaScript

    20

    1 , JavaScript

    , JavaScript . - Java - -, JavaScript Java -. JavaScript 1997 , ECMAScript. - JavaScript, ECMAScript.

    ECMAScript ( - ES3), 1999, JavaScript. ES5 (Edition5), 2009. ES5 - , , , , . ES5 , , ES5, .

    , , - - JavaScript. , JavaScript- const, ECMAScript - . , const . , const, :

  • 1 . , JavaScript

    21

    const PI = 3.141592653589793;PI = "!";

    PI; // 3.141592653589793

    const - var:

    const PI = 3.141592653589793;PI = "!";PI; // "!"

    - - JavaScript, - . , - JavaScript - - JavaScript . -, - .

    JavaScript - - . , . JavaScript. - - JavaScript .

    - JavaScript. , . - , -, . ,

  • 1 . JavaScript

    22

    , . , const , - , --, .

    ES5 . JavaScript, -, - . , , - , . :

    "use strict";

    , :

    function f(x) { "use strict"; // ...}

    - , : , ES3 . , JavaScript-, : , -

  • 1 . , JavaScript

    23

    . ES5, , ES5:

    function f(x) { "use strict"; var arguments = []; // : // arguments

    // ...}

    arguments , , , . , ES5. , ES5.

    , "use strict" , - , , - . , :

    // file1.js"use strict";function f() { // ...}// ...

    , :

    // file2.js//

    function g() {

  • 1 . JavaScript

    24

    var arguments = []; // ...}// ...

    ? file1 .js, :

    // file1.js"use strict";function f() { // ...}// ...// file2.js//

    function f() { var arguments = []; // : // arguments

    // ...}// ...

    file2 .js, - :

    // file2.js//

    function g() { var arguments = []; // ...}// ...// file1.js"use strict";function f() { // //

    // ...}// ...

  • 1 . , JavaScript

    25

    - , , , .

    , - , , .

    , , , , , . , , , , .

    , - - (Immediately Invoked Function Expression, IIFE).

    13, , - - . :

    //

    (function() { // file1.js "use strict"; function f() { // ... } // ...})();

  • 1 . JavaScript

    26

    (function() { // file2.js //

    function f() { var arguments = []; // ... } // ...})();

    , ( ) . - . , var function ( 8). , , - . , , .

    , .

    , - , , - , , . - , - ,

  • 1 . , JavaScript

    . , IIFE, IIFE , , - , :

    (function() { "use strict"; function f() { // ... } // ...})();

    , , - -. , , , , -. , , , .

    , JavaScript - .

    , JavaScript , .

    , , - , .

    , - - .

  • 1 . JavaScript

    28

    2

    - , JavaScript . typeof, :

    typeof 17; // ""

    typeof 98.6; // ""

    typeof -2.1; // ""

    JavaScript , 64-- , IEEE754, doubles ( ). -, , , - 53. 9007199254740992 (253) 9007199254740992 (253) . , JavaScript .

    - , :

    0.1 * 1.9 // 0.19-99 + 100; // 121 - 12.3; // 8.72.5 / 5; // 0.521 % 8; // 5

    - . , 32--

  • 2 .

    29

    . (, 32- - .) , , OR ():

    8 | 1; // 9

    . , JavaScript- 8 1 , 32- , , . 32- 8 :

    00000000000000000000000000001000

    , toString:

    (8).toString(2); // "1000"

    toString - , - 2 ( ). , , .

    1 32- - :

    00000000000000000000000000000001

    OR , - (1), , :

    00000000000000000000000000001001

    9. -

  • 1 . JavaScript

    30

    parseInt, 2:

    parseInt("1001", 2); // 9

    ( , .)

    - , - , , JavaScript . , JavaScript- : , , . , , , - .

    , - : , , , . , , , . , , :

    0.1 + 0.2; // 0.30000000000000004

    64- -, , . , .

  • 2 .

    31

    , , . - , . , - , , x, y z :

    (x + y) + z = x + (y + z).

    - :

    (0.1 + 0.2) + 0.3; // 0.60000000000000010.1 + (0.2 + 0.3); // 0.6

    - . , , . , , .

    , , - , . - . , , , :

    (10 + 20) + 30; // 6010 + (20 + 30); // 60

    , , , 253 253. .

  • 1 . JavaScript

    32

    JavaScript . JavaScript ,

    .

    , 32- .

    , - .

    3

    , JavaScript , . :

    3 + true; // 4

    , true . . - , . JavaScript , 4!

    JavaScript. , , - null:

    "hello"(1); // :

    null.x; // : // 'x' null

  • 3 .

    33

    , - , JavaScript - , . , -, *, / % - . + , , - :

    2 + 3; // 5"hello" + " world"; // "hello world"

    ? JavaScript :

    "2" + 3; // "23"2 + "3"; // "23"

    -, - . :

    1 + 2 + "3"; // "33"

    ( ), :

    (1 + 2) + "3"; // "33"

    :

    1 + "2" + 3; // "123"

    "123" , :

    (1 + "2") + 3; // "123"

  • 1 . JavaScript

    34

    , , 32- , 2. (~, &, ^ |) ( >>>).

    , - , - , :

    "17" * 3; // 51"8" | "1"; // 9

    - . , - null, , 0; NaN, (not a number), - IEEE- ! , - . , - NaN, .

    -, JavaScript - IEEE- , NaN . - NaN :

    var x = NaN;x === NaN; // false

    , isNaN , , -

  • 3 .

    35

    . ( isNaN, , coercesToNaN, NaN.) , , - NaN isNaN:

    isNaN(NaN); // true

    , - NaN, NaN, NaN:

    isNaN("foo"); // trueisNaN(undefined); // trueisNaN({}); // trueisNaN({ valueOf: "foo" }); // true

    , NaN , - . NaN JavaScript-, , NaN - :

    var a = NaN;a !== a; // true

    var b = "foo";b !== b; // false

    var c = undefined;c !== c; // false

    var d = {};d !== d; // false

    var e = { valueOf: "foo" };

    e !== e; // false

    :

    function isReallyNaN(x) { return x !== x;

    }

  • 1 . JavaScript

    36

    , - , .

    , , - . , , , , - . - , , . , , , .

    . :

    "the Math object: " + Math; // "the Math object: // [object Math]""the JSON object: " + JSON; // "the JSON object: // [object JSON]"

    toString. -, :

    Math.toString(); // "[object Math]"JSON.toString(); // "[object JSON]"

    , valueOf. , :

    "J" + { toString: function() { return "S"; } }; // "JS"

    2 * { valueOf: function() { return 3; } }; // 6

  • 3 .

    37

    , + , - . , , toString, valueOf, , +: , , , ! JavaScript , valueOf, toString. , :

    var obj = { toString: function() {

    return "[object MyObject]"; }, valueOf: function() {

    return 17; }};"object: " + obj; // "object: 17"

    , valueOf , - , Number. toString valueOf -+ , , . , , . valueOf, - obj.toString() , obj.valueOf().

  • 1 . JavaScript

    38

    - . , if, || &&, , , . JavaScript - - . JavaScript , true. - - , - . : false, 0, -0, "", NaN undefined. . , - . , - , :

    function point(x, y) { if (!x) {

    x = 320; } if (!y) {

    y = 240; } return { x: x, y: y };

    }

    , 0:

    point(0, 0); // { x: 320, y: 240 }

    - typeof:

    function point(x, y) { if (typeof x === "undefined") { x = 320; }

  • 3 .

    39

    if (typeof y === "undefined") { y = 240; } return { x: x, y: y };

    }

    point 0 undefined:

    point(); // { x: 320, y: 240 }

    point(0, 0); // { x: 0, y: 0 }

    undefined:

    if (x === undefined) { ... }

    API 54.

    , , - .

    + - .

    valueOf toString .

    , valueOf , toString, , valueOf .

    typeof undefined, .

  • 1 . JavaScript

    40

    4 ,

    JavaScript : , , -, null undefined. ( , typeof null - "object", ECMA-Script .) , , . String, :

    var s = new String("hello");

    , String , . :

    s + " world"; // "hello world"

    :

    s[4]; // "o"

    , String :

    typeof "hello"; // "string"typeof s; // "object"

    , - String :

    var s1 = new String("hello");var s2 = new String("hello");s1 === s2; // false

  • 4 . ,

    41

    String - , . :

    s1 == s2; // false

    - , . . JavaScript : , , - . , String toUpperCase, . :

    "hello".toUpperCase(); // "HELLO"

    - , - :

    "hello".someProperty = 17;"hello".someProperty; // undefined

    String, . , JavaScript . , , - JavaScript , - : , , . .

  • 1 . JavaScript

    42

    , .

    .

    5 ==

    , -:

    "1.0e0" == { valueOf: function() { return true; } };

    , , == -, - (. 3), . "1.0e0" 1, valueOf (true) , 1.

    , - :

    var today = new Date();

    if (form.month.value == (today.getMonth() + 1) && form.day.value == today.getDate()) { // !

    // ...}

  • 5 . ==

    43

    , Number +:

    var today = new Date();

    if (+form.month.value == (today.getMonth() + 1) && +form.day.value == today.getDate()) { // !

    // ...}

    , - , . - :

    var today = new Date();

    if (+form.month.value === (today.getMonth() + 1) && //

    +form.day.value === today.getDate()) { //

    // !

    // ...}

    , == === . , , , . - , . , - , .

    , . -1.1 -

  • 1 . JavaScript

    ==, -. , null == undefined, undefined == null. , - . , valueOf toString, - . Date, .

    1.1. ==

    1 2

    null undefined ; true

    null undefined , null

    undefined

    ; false

    ,

    Date => , Date

    => (

    toString, valueOf)

    ,

    , -

    Date

    => , ,

    Date=>

    ( valueOf,

    toString)

    ,

    ,

    =>

  • 5 . ==

    45

    , == . , . - . JavaScript , , .

    , , , Date:

    var date = new Date("1999/12/31");date == "1999/12/31"; // false

    , Date -, , :

    date.toString(); // "Fri Dec 31 1999 00:00:00 GMT-0800 (PST)"

    - . == - . - , . , - :

    function toYMD(date) { var y = date.getYear() + 1900, // // // 1900

    m = date.getMonth() + 1, // // // 0

    d = date.getDate(); return y + "/" + (m < 10 ? "0" + m : m)

    + "/" + (d < 10 ? "0" + d : d);

    }toYMD(date) === "1999/12/31"; // true

  • 1 . JavaScript

    46

    , , - ==, , , .

    == .

    , - , === .

    , - .

    6

    , JavaScript, - , -. , :

    function Point(x, y) { this.x = x || 0 this.y = y || 0}

    Point.prototype.isOrigin = function() { return this.x === 0 && this.y === 0}

  • 6 .

    47

    , , - . ECMAScript , JavaScript.

    , , 3 5, , . , JavaScript , . , , , - .

    :

    } .

    , , . , :

    function square(x) { var n = +x return n * n}function area(r) { r = +r; return Math.PI * r * r }function add1(x) { return x + 1 }

    :

    function area(r) { r = +r return Math.PI * r * r } //

  • 1 . JavaScript

    48

    :

    , .

    , - .

    :

    a = b(f());

    -, :

    a = b(f());

    . - :

    a = bf();

    , :

    a = b f();

    : , , . , -.

    -: (, [, +, - /. , -

  • 6 .

    49

    , . , , -. , . , , , , - , . :

    a = b["r", "g", "b"].forEach(function(key) { background[key] = foreground[key] / 2;});

    : , , "r", "g" "b". [, , :

    a = b["r", "g", "b"].forEach(function(key) { background[key] = foreground[key] / 2;});

    , , JavaScript - , - "b".

    +, - / - , . /. , -:

    /Error/i.test(str) && fail();

    - /Error/i.

  • 1 . JavaScript

    50

    , - fail. , :

    a = b/Error/i.test(str) && fail();

    :

    a = b / Error / i.test(str) && fail();

    , / - !

    JavaScript-, , - , , , -. . , :

    a = b //

    var x //

    (f()) //

    - :

    var x //

    a = b //

    (f()) //

    , var ( 12), , b , , :

    var x;a = b(f());

  • 6 .

    51

    , , , , -. , , - (, [, +, - /. , :

    a = b //

    var x //

    ;(f()) //

    - var , :

    var x //

    a = b //

    ;(f()) //

    -, , (.1). - ( - - 13):

    // file1.js(function() { // ...})()

    // file2.js(function() { // ...})()

    -, , . -, :

  • 1 . JavaScript

    52

    (function() { // ...})()(function() { // ...})()

    , :

    (function() { // ...})()(function() { // ...})();

    , , - , , . , , (, [, +, - /:

    // file1.js;(function() { // ...})()

    // file2.js;(function() { // ...})()

    , - :

    ;(function() { // ...

  • 6 .

    53

    })();(function() { // ...})()

    , , - . , , .

    : - . , . : , JavaScript -, , - . - JavaScript, - . return, - return - . :

    return { };

    :

    return{ };

    - :

    return;{ };

    , - , return, ,

  • 1 . JavaScript

    54

    return , . - :

    yy throw;

    yy break continue ;

    yy ++ --. - :

    a++b

    ++ , , -- , :

    a; ++b;

    :

    for .

    , for . :

    for (var i = 0, total = 1 // //

    i < n i++) { total *= i}

  • 55

    7 . 16-

    . - :

    function infiniteLoop() { while (true) } //

    , :

    function infiniteLoop() { while (true); }

    }, .

    , .

    , (, [, +, - / .

    .

    - , - return, throw, break continue, ++ -- .

    - for .

    7 16-

    - ,

  • 1 . JavaScript

    56

    , , . . : - 0 1114111, - (code point). , - , ASCII. , , ASCII - -, . -, , , . , - UTF-8, UTF-16 UTF-32.

    , - . , 216 . - UCS-2, 16- , . 16- , - , (code units). UCS-2 16- , . - , , : n- n-16- . .1.1 - , 16- . , - .

  • 57

    7 . 16-

    0x0068

    0 1 2 3 4

    'h' 'e' 'l' 'l' 'o'

    0x0065 0x006c 0x006c 0x006f

    . 1.1. JavaScript-

    16-- . Java, JavaScript : - JavaScript- 16- . , 1990-, JavaScript- - .

    16- , , ASCII . , , 220 .

    17 216 . , (Basic Multilingual Plane, BMP), 216 . 16 - .

    , - UCS-2 : - . , UTF-16, , -: 16- , 216 . , ,

  • 1 . JavaScript

    58

    U+1D11E, 119070 UTF-16 0xd834 0xdd1e. , - . ( -, BMP, , , - .) .1.2. , .

    0xd834

    0 1 2 3 4 5 6

    ' ' ' 'c' 'l' 'e' 'f'

    0xdd1e 0x0020 0x0063 0x006c 0x0065 0x0066

    '

    . 1.2. JavaScript-,

    UTF-16 , 16- - , UTF-16 : n . , n- : , , .

    , JavaScript 16- . , length, charAt charCodeAt, , .

  • 59

    7 . 16-

    - , JavaScript , - , UTF-16. :

    JavaScript- 16- .

    JavaScript- - . , , UTF-16. .1.2. , , JavaScript , 7:

    " clef".length; // 7"G clef".length; // 6

    , :

    " clef".charCodeAt(0); // 55348 (0xd834)" clef".charCodeAt(1); // 56606 (0xdd1e)" clef".charAt(1) === " "; // false" clef".charAt(2) === " "; // true

    . (".") :

    /^.$/.test(""); // false/^..$/.test(""); // true

    , , - , : , length, -

  • 1 . JavaScript

    . BMP, - , . - , , .

    JavaScript - , API- - . , ECMAScript- ; , , URI-: encodeURI, decodeURI, encodeURIComponent decode-URIComponent. JavaScript , , - - - , , , - .

    JavaScript- 16- , .

    216 JavaScript , .

    , length, charAt, charCodeAt , . .

    , , .

    , , , , .

  • 61

    2.

    . . . ..., .

    , -, JavaScript, , . . JavaScript , , , .

    8

    JavaScript . , . - .

  • 2 .

    62

    , - . , . : - . , -, , , .

    - , . - , . . , -, -. , , , :

    var i, n, sum; //

    function averageScore(players) { sum = 0; for (i = 0, n = players.length; i < n; i++) { sum += score(players[i]); } return sum / n;}

    averageScore -, score, , - :

  • 8 .

    63

    var i, n, sum; // , // averageScore!function score(player) { sum = 0; for (i = 0, n = player.levels.length; i < n; i++) { sum += player.levels[i].score; } return sum;}

    -, , :

    function averageScore(players) { var i, n, sum; sum = 0; for (i = 0, n = players.length; i < n; i++) { sum += score(players[i]); } return sum / n; }function score(player) { var i, n, sum; sum = 0; for (i = 0, n = player.levels.length; i < n; i++) { sum += player.levels[i].score; } return sum;}

    JavaScript - , this. - window. :

    this.foo; // foo = "global foo";this.foo; // "global foo"

  • 2 .

    64

    , - - :

    var foo = "global foo";this.foo = "changed";foo; // "changed"

    , - : -, var, -, - . , var , , . , , - , .

    , , - . -, , . , ES5 JSON, JSON. , - JSON, :

    if (!this.JSON) {

    this.JSON = { parse: ...,

    stringify: ...

    };}

  • 9 .

    65

    JSON, , , . , - , : -, .

    -, - . - , . , , - , JavaScript-.

    . . . -

    .

    9

    , , . , JavaScript .

  • 2 .

    66

    , - , . , , - :

    function swap(a, i, j) { temp = a[i]; //

    a[i] = a[j]; a[j] = temp;}

    , - var temp - . temp var:

    function swap(a, i, j) { var temp = a[i]; a[i] = a[j]; a[j] = temp;}

    - , - . - - -, , . . -- ( , , ), , - , - . , JavaScript, .

  • 10 . with

    67

    - , , .

    var .

    -, - .

    10 with

    with. , JavaScript . with - : -.

    with . - , :

    function status(info) { var widget = new Widget(); with (widget) { setBackground("blue"); setForeground("white"); setText("Status: " + info); // //

    show(); }}

  • 2 .

    68

    with - , :

    function f(x, y) { with (Math) { return min(round(x), sqrt(y)); //

    }}

    with - .

    . - , . , : -, , , , - with ( setBackground, round sqrt), -, , , , ( info, x y). .

    , JavaScript -: , , . with , with - . , .

    .2.1 - JavaScript- status, - with. ES5 (lexical environment), (scope chain).

  • 10 . with

    69

    widget. - info widget. status. , , - , - , . with , .

    ._background

    widget

    ._foreground

    . . .

    .info

    .widget

    .status

    .setBackground

    Widget.prototype

    .setForeground

    .setText

    .show

    . . .

    .hasOwnProperty

    Object.prototype

    .toString

    .valueOf

    . . .

    . 2.1. ( ) status

    , , , with,

  • 2 .

    70

    ? - with -, with . , with , -. , , , .

    with . , widget - info, status - info, . - , , , , info.

    , info - - Widget, status :

    status("connecting"); // Status: connecting

    Widget.prototype.info = "[[widget info]]";status("connected"); // Status: [[widget info]]

    f, - Math x y:

    Math.x = 0;Math.y = 0;f(2, 9); // 0

    , , - - Math x y, , . , -

  • 10 . with

    71

    , , . JavaScript - , . with , - , , , , .

    JavaScript - with. :

    function status(info) { var w = new Widget(); w.setBackground("blue"); w.setForeground("white"); w.addText("Status: " + info);

    w.show();}

    . w. - Widget, status :

    status("connecting"); // Status: connecting

    Widget.prototype.info = "[[widget info]]";status("connected"); // Status: connected

    :

    function f(x, y) { var min = Math.min, round = Math.round, sqrt = Math.sqrt; return min(round(x), sqrt(y));}

  • 2 .

    72

    , with, :

    Math.x = 0;Math.y = 0;f(2, 9); // 2

    with . -

    .

    with .

    11

    , , . -, , , , .

    , . , . , JavaScript - , :

    function makeSandwich() { var magicIngredient = "peanut butter"; function make(filling) { return magicIngredient + " and " + filling; } return make("jelly");}makeSandwich(); // "peanut butter and jelly"

  • 11 .

    73

    , make magicIngredient, makeSandwich.

    , , , ! - , , JavaScript (.19). , :

    function sandwichMaker() { var magicIngredient = "peanut butter"; function make(filling) { return magicIngredient + " and " + filling; } return make;}var f = sandwichMaker();f("jelly"); // "peanut butter and jelly"f("bananas"); // "peanut butter and bananas"f("marshmallows"); // "peanut butter and marshmallows"

    , make("jelly") - , sandwichMaker make. f make, f make. , , sandwichMaker , make magicIngredient.

    ? , JavaScript- - , . , . , -, (closures). make ,

  • 2 .

    74

    : magicIngredient filling. make , .

    , . sandwichMaker:

    function sandwichMaker(magicIngredient) { function make(filling) { return magicIngredient + " and " + filling; } return make;}var hamAnd = sandwichMaker("ham");hamAnd("cheese"); // "ham and cheese"hamAnd("mustard"); // "ham and mustard"var turkeyAnd = sandwichMaker("turkey");turkeyAnd("Swiss"); // "turkey and Swiss"turkeyAnd("Provolone"); // "turkey and Provolone"

    , hamAnd turkeyAnd. make, - : magicIngredient "ham", "turkey".

    - JavaScript, . JavaScript -:

    function sandwichMaker(magicIngredient) { return function(filling) { return magicIngredient + " and " + filling; };}

  • 11 .

    75

    , - : -, , . - (. 14).

    , - , , . -, . -, . , , (box) , :

    function box() { var val = undefined; return { set: function(newVal) { val = newVal; },

    get: function() { return val; },

    type: function() { return typeof val; }

    };}var b = box();b.type(); // "undefined"b.set(98.6);b.get(); // 98.6b.type(); // "number"

    , set (), get () type ( ). - val. set val, get type -.

  • 2 .

    76

    , - .

    . ,

    , .

    12

    JavaScript (lexical scope): - foo , foo . JavaScript (block scope): , , .

    JavaScript :

    function isWinner(player, others) { var highest = 0; for (var i = 0, n = others.length; i < n; i++) { var player = others[i]; if (player.score > highest) { highest = player.score; } } return player.score > highest;}

    for - player.

  • 12 .

    77

    JavaScript - , , player , , player. . - return player others, player.

    JavaScript , : . JavaScript , - . , - , , var. .2.2.

    function f() { // ... // ... { // ...

    var x = /* ... */; // ... } // ...}

    function f() {var x;

    // ... { // ... x = /* ... */; // ... } // ...}

    . 2.2.

    - . . :

    function trimSections(header, body, footer) { for (var i = 0, n = header.length; i < n; i++) { header[i] = header[i].trim(); }

  • 2 .

    78

    for (var i = 0, n = body.length; i < n; i++) { body[i] = body[i].trim(); } for (var i = 0, n = footer.length; i < n; i++) { footer[i] = footer[i].trim(); }}

    trimSections ( i, - n), . , trimSections :

    function trimSections(header, body, footer) { var i, n; for (i = 0, n = header.length; i < n; i++) { header[i] = header[i].trim(); } for (i = 0, n = body.length; i < n; i++) { body[i] = body[i].trim(); } for (i = 0, n = footer.length; i < n; i++) { footer[i] = footer[i].trim(); }}

    , - var , , . , , , -.

    , JavaScript , , , . trycatch

  • 79

    13 . -

    caught , - catch:

    function test() { var x = "var", result = []; result.push(x); try { throw "exception"; } catch (x) { x = "catch"; } result.push(x); return result;}test(); // ["var", "var"]

    , .

    . , -

    .

    13 -

    (!) :

    function wrapElements(a) { var result = [], i, n; for (i = 0, n = a.length; i < n; i++) {

  • 2 .

    80

    result[i] = function() { return a[i]; }; } return result;}var wrapped = wrapElements([10, 20, 30, 40, 50]);var f = wrapped[0];f(); // ?

    , - 10, undefined.

    . -, . wrapElements : result, i n. wrapElements -. . , , , , i - . i. i , i. .

    , .

    , , wrapElements, i, . i , , ,

  • 81

    13 . -

    , 5 undefined.

    , wrapElements , var for:

    function wrapElements(a) { var result = []; for (var i = 0, n = a.length; i < n; i++) { result[i] = function() { return a[i]; }; } return result;}var wrapped = wrapElements([10, 20, 30, 40, 50]);var f = wrapped[0];f(); // undefined

    , - var . , . , i .

    - :

    function wrapElements(a) { var result = []; for (var i = 0, n = a.length; i < n; i++) { (function() { var j = i; result[i] = function() { return a[j]; }; })(); } return result;}

    , - (Immediately Invoked Function Expression, IIFE), ,

  • 2 .

    JavaScript . - - :

    function wrapElements(a) { var result = []; for (var i = 0, n = a.length; i < n; i++) { (function(j) { result[i] = function() { return a[j]; }; })(i); } return result;}

    IIFE , - . -, break continue, , . -, this arguments, IIFE . this arguments 3.

    . , -

    .

    - - (IIFE) .

    , IIFE .

  • 83

    14 .

    14 , -

    JavaScript- , . :

    function double(x) { return x * 2; }

    , -. : . , double. -, . :

    var f = function double(x) { return x * 2; };

    ECMAScript, f, double. , -, -:

    var f = function(x) { return x * 2; };

    - , - . - -:

    var f = function find(tree, key) { if (!tree) {

    return null; }

  • 2 .

    84

    if (tree.key === key) { return tree.value; } return find(tree.left, key) || find(tree.right, key);};

    , find . , -- :

    find(myTree, "foo"); // : find //

    - , - :

    var f = function(tree, key) { if (!tree) {

    return null; } if (tree.key === key) { return tree.value; } return f(tree.left, key) || f(tree.right, key);};

    :

    function find(tree, key) { if (!tree) {

    return null; } if (tree.key === key) { return tree.value; } return find(tree.left, key) ||

  • 85

    14 .

    find(tree.right, key);}var f = find;

    -- . JavaScript- Error, - - . - .

    , - - - ECMAScript JavaScript- - . , ES3, , JavaScript- - , , - with. , - , , Object.prototype. , - - Object.prototype. :

    var constructor = function() { return null; };var f = function f() { return constructor();};f(); // {} ( ES3)

    , null, , - - Object.prototype.constructor ( -- Object). , with,

  • 2 .

    86

    Object.prototype. Object.prototype - , - .

    , ES5 . JavaScript- . , - -! - null:

    var constructor = function() { return null; };var f = function() { return constructor();};f(); // {} ( , )

    -, - , - Object.prototype , Object.prototype.

    , JavaScript-, -- . :

    var f = function g() { return 17; };g(); // 17 ( , )

    , , . , JavaScript- f g , !

  • 14 .

    , -, null:

    var f = function g() { return 17; };var g = null;

    var g , - -, - null , .

    , , - - - . - , - -. : , - (.1). , , , .

    - Error .

    - - Object.prototype ES3 JavaScript- .

    - - JavaScript- .

    - .

    , ES5, .

  • 2 .

    88

    15 , -

    . , , , . :

    function f() { return "global"; }function test(x) { function f() { return "local"; } var result = []; if (x) { result.push(f()); } result.push(f()); return result;}test(true); // ["local", "local"]test(false); // ["local"]

    f , :

    function f() { return "global"; }function test(x) { var result = []; if (x) { function f() { return "local"; } //

    result.push(f()); } result.push(f()); return result;}

  • 89

    15 .

    test(true); // ?test(false); // ?

    , , test ["local", "global"], ["global"], f if. , JavaScript , - f test. , ["local", "local"] ["local"]. JavaScript- . ! - , f , , . ( , -, with.)

    ECMAScript? , . ES5 - ; -, . ES5 , JavaScript-, , , , . , .

    - -

  • 2 .

    90

    . -, , . , var -:

    function f() { return "global"; }function test(x) { var g = f, result = []; if (x) { g = function() { return "local"; } result.push(g()); } result.push(g()); return result;}

    ( g): , -. .

    , -, - .

    var .

  • 16 . eval

    91

    16 Eval

    JavaScript eval . , . - eval .

    eval JavaScript-, . :

    function test(x) { eval("var y = x;"); //

    return y;}test("hello"); // "hello"

    , - -, var, test. var - eval. eval :

    var y = "global";function test(x) { if (x) { eval("var y = 'local';"); //

    } return y;}test(true); // "local"test(false); // "global"

  • 2 .

    92

    , , . , , , . , - , eval, :

    var y = "global";function test(src) { eval(src); //

    return y;}test("var y = 'local';"); // "local"test("var z = 'local';"); // "global"

    : - - test. , eval , , - - ES5, eval , . eval :

    var y = "global";function test(src) { (function() { eval(src); })(); return y;}test("var y = 'local';"); // "global"test("var z = 'local';"); // "global"

  • 17 . eval

    93

    eval, .

    , eval, -, .

    17 Eval

    eval . , , . eval , . , - , eval , - , , eval.

    eval. eval eval:

    var x = "global";function test() { var x = "local"; return eval("x"); // eval

    }test(); // "local"

  • 2 .

    94

    - , -. , . , eval - , :

    var x = "global";function test() { var x = "local"; var f = eval; return f("x"); // eval

    }test(); // "global"

    eval , ECMAScript. , , eval, - eval, , ( ). eval - (,) :

    (0,eval)(src);

    -? 0 , , eval. , (0,eval) , eval, : eval.

    eval - .

  • 17 . eval

    95

    , , , - . 16 , eval, , . , eval . , , eval - , , .

    eval . , - , eval.

    eval, eval .

    eval, .

  • 96

    3.

    JavaScript, - , . , : , , . JavaScript. , - .

    18 ,

    - -, , , , . JavaScript - .

  • 18 . ,

    97

    :

    function hello(username) { return "hello, " + username;}hello("Keyser Sze"); // "hello, Keyser Sze"

    , : - hello username .

    JavaScript , , :

    var obj = { hello: function() {

    return "hello, " + this.username; }, username: "Hans Gruber"

    };obj.hello(); // "hello, Hans Gruber"

    , hello - obj this. , this obj, hello obj. :

    var obj2 = { hello: obj.hello,

    username: "Boo Radley"

    };obj2.hello(); // "hello, Boo Radley"

    this, , , . obj.hello() hello obj obj. obj2.hello() hello - obj2 ( , obj.hello), obj2.

  • 3 .

    98

    , , - .

    , , , this :

    function hello() { return "hello, " + this.username;}

    :

    var obj1 = { hello: hello,

    username: "Gordon Gekko"

    };obj1.hello(); // "hello, Gordon Gekko"

    var obj2 = { hello: hello,

    username: "Biff Tannen"

    };obj2.hello(); // "hello, Biff Tannen"

    , this, - ( ):

    hello(); // "hello, undefined"

    , , - , username undefined. - , this, , , . , -

  • 18 . ,

    99

    -, ES5 this undefined:

    function hello() { "use strict"; return "hello, " + this.username;}hello(); // : // "username", // (undefined) //

    - , : undefined - .

    -. , , function:

    function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash;}

    User new :

    var u = new User("sfalken", "0ef33ae791068ec64b502d6cb0191387");u.name; // "sfalken"

    , - this . - - .

  • 3 .

    100

    , .

    ( undefined , ) . - .

    new .

    19

    - -; , , - . . . , .

    , -, -. ( , ) -, , JavaScript.

    sort -. ,

  • 19 .

    101

    sort , :

    function compareNumbers(x, y) { if (x < y) { return -1; } if (x > y) { return 1; } return 0;}[3, 1, 4, 1, 5, 9].sort(compareNumbers); // [1, 1, 3, // 4, 5, 9]

    - , - , . , , :

    [3, 1, 4, 1, 5, 9].sort(function(x, y) { if (x < y) { return -1; } if (x > y) { return 1; } return 0;}); // [1, 1, 3, 4, 5, 9]

    - . , . . , :

  • 3 .

    102

    var names = ["Fred", "Wilma", "Pebbles"];var upper = [];for (var i = 0, n = names.length; i < n; i++) { upper[i] = names[i].toUpperCase();}upper; // ["FRED", "WILMA", "PEBBLES"]

    map, - ( ES5). , :

    var names = ["Fred", "Wilma", "Pebbles"];var upper = names.map(function(name) { return name.toUpperCase();});upper; // ["FRED", "WILMA", "PEBBLES"]

    , -. . , , :

    var aIndex = "a".charCodeAt(0); // 97var alphabet = "";for (var i = 0; i < 26; i++) { alphabet += String.fromCharCode(aIndex + i);}alphabet; // "abcdefghijklmnopqrstuvwxyz"

    , :

    var digits = "";for (var i = 0; i < 10; i++) { digits += i;}digits; // "0123456789"

  • 19 .

    103

    - - :

    var random = "";for (var i = 0; i < 8; i++) { random += String.fromCharCode(Math.floor(Math.random() * 26) + aIndex);}random; // "bdwvfrtp" ( // )

    , , . . :

    function buildString(n, callback) { var result = ""; for (var i = 0; i < n; i++) { result += callback(i); } return result;}

    , buildString , - : n, - . buildString :

    var alphabet = buildString(26, function(i) { return String.fromCharCode(aIndex + i);});alphabet; // "abcdefghijklmnopqrstuvwxyz"var digits = buildString(10, function(i) { return i; });digits; // "0123456789"

  • 3 .

    var random = buildString(8, function() { return String.fromCharCode(Math.floor(Math.random() * 26) + aIndex);});random; // "ltvisfjr" ( // )

    . -, , , , - . , , . - , , - . , , buildString, , , , , .

    , , , - . - .

    , .

    . ,

    .

  • 20 . call

    105

    20 call

    ( , this) - . , this - . , , - -. , :

    obj.temporary = f; // obj.temporary // ?

    var result = obj.temporary(arg1, arg2, arg3);delete obj.temporary; // obj.temporary // ?

    . - obj. , temporary, obj. , , - - . , , - , (.42).

    , call. call:

    f.call(obj, arg1, arg2, arg3);

    , :

    f(arg1, arg2, arg3);

  • 3 .

    106

    , call - -.

    call , , . 45 - , hasOwnProperty , . - hasOwnProperty -, :

    dict.hasOwnProperty = 1;dict.hasOwnProperty("foo"); // : 1 //

    call hasOwn-Property , - :

    var hasOwnProperty = {}.hasOwnProperty;dict.foo = 1;delete dict.hasOwnProperty;hasOwnProperty.call(dict, "foo"); // truehasOwnProperty.call(dict, "hasOwnProperty"); // false

    call . - . , , -, forEach:

    var table = { entries: [],

    addEntry: function(key, value) {

    this.entries.push({ key: key, value: value });

    }, forEach: function(f, thisArg) {

    var entries = this.entries; for (var i = 0, n = entries.length; i < n; i++) {

  • 21 . apply

    107

    var entry = entries[i]; f.call(thisArg, entry.key, entry.value, i); } }};

    f table.forEach . , :

    table1.forEach(table2.addEntry, table2);

    addEntry table2 ( Table.prototype table1), - forEach addEntry table2, . , addEntry , forEach : , -. () , addEntry .

    call . call ,

    .

    call , .

    21 apply

    , - , - :

  • 3 .

    108

    average(1, 2, 3); // 2average(1); // 1average(3, 1, 4, 1, 5, 9, 2, 6, 5); // 4average(2, 7, 1, 8, 2, 8, 1, 8); // 4.625

    average , - ( ): . , average , , , :

    averageOfArray([1, 2, 3]); // 2averageOfArray([1]); // 1averageOfArray([3, 1, 4, 1, 5, 9, 2, 6, 5]); // 4averageOfArray([2, 7, 1, 8, 2, 8, 1, 8]); // 4.625

    , , . - , , , , , . , :

    var scores = getAllScores();

    average ?

    average(/* ? */);

    , - apply, call, . apply , .

    , apply , this . average this, null:

  • 21 . apply

    109

    var scores = getAllScores();average.apply(null, scores);

    scores , , , :

    average(scores[0], scores[1], scores[2]);

    apply - . , buffer - append, ( append, - 22):

    var buffer = { state: [],

    append: function() {

    for (var i = 0, n = arguments.length; i < n; i++) { this.state.push(arguments[i]); } }};

    -:

    buffer.append("Hello, ");buffer.append(firstName, " ", lastName, "!");

    buffer.append(newline);

    apply this, append :

    buffer.append.apply(buffer, getInputStrings());

    buffer: , append state .

  • 3 .

    110

    apply .

    apply .

    22 arguMEntS

    21 average, . ? averageOfArray - :

    function averageOfArray(a) { for (var i = 0, sum = 0, n = a.length; i < n; i++) { sum += a[i]; } return sum / n;}averageOfArray([2, 7, 1, 8, 2, 8, 1, 8]); // 4.625

    averageOfArray - a. avera-geOfArray, ( , - ) .

    , - .

  • 22 . arguments

    111

    , JavaScript - arguments. arguments , , : - , length - . average , - arguments:

    function average() { for (var i = 0, sum = 0, n = arguments.length; i < n; i++) { sum += arguments[i]; } return sum / n;}

    -, . : , - apply (.21). , . , , - :

    function average() { return averageOfArray(arguments);}

    - apply, -.

  • 3 .

    112

    argu-ments .

    apply, - .

    23 arguMEntS

    arguments , , -, , . , - Perl UNIX, . JavaScript- , , shift, . arguments Array, arguments.shift() .

    call - shift arguments. , callMethod, :

    function callMethod(obj, method) { var shift = [].shift; shift.call(arguments); shift.call(arguments); return obj[method].apply(obj, arguments);}

  • 23 . arguments

    113

    - :

    var obj = { add: function(x, y) { return x + y; }

    };callMethod(obj, "add", 17, 25);// : "apply",

    // (undefined)

    , arguments - . , - arguments. obj argu-ments[0], method arguments[1] , arguments shift. , , obj["add"], 17[25]! : , 17 Number, - "25" ( ), (undefined), - undefined .

    , arguments . , arguments, - . ES5. - arguments. , , , - arguments:

    function strict(x) { "use strict"; arguments[0] = "modified";

  • 3 .

    114

    return x === arguments[0];}function nonstrict(x) { arguments[0] = "modified"; return x === arguments[0];}strict("unmodified"); // falsenonstrict("unmodified"); // true

    , - arguments. , . - :

    var args = [].slice.call(arguments);

    slice -, Array. - - Array, .

    callMethod, , obj method, slice , 2:

    function callMethod(obj, method) { var args = [].slice.call(arguments, 2); return obj[method].apply(obj, args);}

    callMethod , -:

    var obj = { add: function(x, y) { return x + y; }

    };callMethod(obj, "add", 17, 25); // 42

  • 24 . arguments

    115

    arguments .

    arguments , [].slice.call(arguments) .

    24 arguMEntS

    , - . API- next, . , , , :

    var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6);it.next(); // 1it.next(); // 4it.next(); // 1

    values -, , - arguments:

    function values() { var i = 0, n = arguments.length; return { hasNext: function() {

    return i < n; }, next: function() {

  • 3 .

    116

    if (i >= n) { throw new Error(" ");

    } return arguments[i++]; // //

    } };}

    , -:

    var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6);it.next(); // (undefined)

    it.next(); // (undefined)

    it.next(); // (undefined)

    , argu-ments . arguments values, next arguments. arguments[i++], it.next, arguments, .

    : - arguments , :

    function values() { var i = 0, n = arguments.length, a = arguments; return { hasNext: function() {

    return i < n; }, next: function() {

    if (i >= n) { throw new Error(" ");

    }

  • 25 . bind

    117

    return a[i++]; } };}var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6);it.next(); // 1it.next(); // 4it.next(); // 1

    arguments - .

    arguments , arguments, .

    25 bind

    , , - . , , . , , :

    var buffer = { entries: [],

  • 3 .

    118

    add: function(s) {

    this.entries.push(s); }, concat: function() {

    return this.entries.join(""); }};

    - add ES5- forEach:

    var source = ["867", "-", "5309"];source.forEach(buffer.add); // : // (undefined)

    buffer.add . , , . forEach, - - . , forEach . entries, . , forEach - , , :

    var source = ["867", "-", "5309"];source.forEach(buffer.add, buffer);buffer.join(); // "867-5309"

    - , . forEach - , ? , buffer.add:

  • 25 . bind

    119

    var source = ["867", "-", "5309"];source.forEach(function(s) { buffer.add(s);});buffer.join(); // "867-5309"

    -, add . - , - this. - , - call, .

    , - , , ES5 . bind, - -, . bind, :

    var source = ["867", "-", "5309"];source.forEach(buffer.add.bind(buffer));buffer.join(); // "867-5309"

    , buffer.add.bind(buffer) buffer.add, . , , , . , :

    buffer.add === buffer.add.bind(buffer); // false

    , , , bind , - . , --

  • 3 .

    120

    : - . ( 4.)

    , .

    .

    , - , bind .

    26 bind

    bind . URL- :

    function simpleURL(protocol, domain, path) { return protocol + "://" + domain + "/" + path;

    }

    URL- . - ES5- map :

    var urls = paths.map(function(path) { return simpleURL("http", siteDomain, path);});

  • 26 . bind

    , map; simpleURL , . - simpleURL bind:

    var urls = paths.map(simpleURL.bind(null, "http", siteDomain));

    simpleURL.bind -, simpleURL. , bind -. ( simpleURL this, , null undefined.) , simpleURL, simpleURL.bind , - . , - simpleURL.bind path, simpleURL("http", siteDomain, path).

    - (currying) (Haskell Curry), . - -.

    , , , bind .

    , , null undefined .

  • 3 .

    122

    27 ,

    , - . , map forEach, JavaScript - - (.7). , - eval. , , ?

    , . - : .

    - :

    function repeat(n, action) { for (var i = 0; i < n; i++) { eval(action); }}

    , , , - eval . , , , start end:

    var start = [], end = [], timings = [];repeat(1000, "start.push(Date.now()); f(); end.push(Date.now())");

  • 27 . ,

    123

    for (var i = 0, n = start.length; i < n; i++) { timings[i] = end[i] - start[i];}

    . - , start end :

    function benchmark() { var start = [], end = [], timings = []; repeat(1000, "start.push(Date.now()); f(); end.push(Date.now())"); for (var i = 0, n = start.length; i < n; i++) { timings[i] = end[i] - start[i]; } return timings;}

    repeat start end. , benchmark ReferenceError. , , push - - , start end, .

    API- :

    function repeat(n, action) { for (var i = 0; i < n; i++) { action(); }}

    , benchmark , :

  • 3 .

    124

    function benchmark() { var start = [], end = [], timings = []; repeat(1000, function() { start.push(Date.now()); f(); end.push(Date.now()); }); for (var i = 0, n = start.length; i < n; i++) { timings[i] = end[i] - start[i]; } return timings;}

    , eval, - , , , , - , . , , , .

    , API-, eval .

    API-, , , eval .

    28 toString

    JavaScript - :

  • 28 . toString

    125

    (function(x) { return x + 1;}).toString(); // "function (x) // {\n return x + 1;\n}"

    - , . toString - .

    , ECMAScript , toString. , JavaScript- - , , .

    , JavaScript- , - JavaScript. , :

    (function(x) { return x + 1;}).bind(16).toString(); // "function (x) // {\n [native code]\n}"

    bind - ( C++), , - JavaScript, .

    - toString, , - JavaScript-, . JavaScript (, - ) , .

  • 3 .

    126

    , , to-String, , -, -. :

    (function(x) { return function(y) { return x + y; }})(42).toString(); // "function (y) // {\n return x + y;\n}"

    , - - x, -, x 42.

    , . - JavaScript- . - , JavaScript- , .

    toString JavaScript- .

    - -, toString .

    toString - , .

    , toString .

  • 29 .

    127

    29

    JavaScript- : - ( . 64). arguments : arguments.callee , arguments, - arguments.caller , . - , , :

    var factorial = (function(n) { return (n

  • 3 .

    128

    function start() { return revealCaller();}start() === start; // true

    - , . :

    function getCallStack() { var stack = []; for (var f = getCallStack.caller; f; f = f.caller) { stack.push(f); } return stack;}

    getCallStack :

    function f1() { return getCallStack();}function f2() { return f1();}var trace = f2();trace; // [f1, f2]

    getCallStack : , !

    function f(n) { return n === 0 ? getCallStack() : f(n - 1);

    }var trace = f(1); //

  • 29 .

    129

    ? f , caller , f. getCallStack , f. , , f , .

    . , ES5; caller callee - arguments :

    function f() { "use strict"; return f.caller;}f(); // : caller

    //

    . - , - .

    arguments.caller ar-guments.callee, .

    caller , - .

  • 130

    4.

    JavaScript -. - . , .

    - , JavaScript : - . , JavaScript , . JavaScript - , .

    - , , . JavaScript . . - , . - , - .

  • 131

    30 .

    30 prototypE, gEtprototypEof __proto__

    , , prototype. - . .

    yy C.prototype - , new C().

    yy Object.getPrototypeOf(obj) ( ES5) obj.

    yy obj.__proto__ obj.

    , - JavaScript. User , - new , :

    function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash;}

    User.prototype.toString = function() { return "[User " + this.name + "]";};

    User.prototype.checkPassword = function(password) { return hash(password) === this.passwordHash;};

    var u = new User("sfalken", "0ef33ae791068ec64b502d6cb0191387");

  • 4 .

    132

    User prototype, , - - . User.prototype : toString checkPassword. User new, - u , - User.prototype, -. .4.1.

    . 4.1. User

  • 133

    30 .

    , - u - User.prototype. . , u.name u.passwordHash, u. , u, u. , u.checkPassword , User.prototype.

    . prototype - , ES5 Object.getPrototypeOf() - . , , u :

    Object.getPrototypeOf(u) === User.prototype; // true

    - __proto__. , ES5- Object.getPrototypeOf. :

    u.__proto__ === User.prototype // true

    , : JavaScript- User , . JavaScript - - (User) -, - (User.prototype).

    . 4.2 User. User , User.prototype ,

  • 4 .

    . - User u - .

    . 4.2. User

    C.prototype - new C() .

    Object.getPrototypeOf(obj) , - ES5 .

    obj.__proto__ - .

    , -- .

  • 135

    31 . Object .getPrototypeOf

    31 obJEct.gEtprototypEof, __proto__

    API- -- ES5 Object.getPrototypeOf, , JavaScript- - __proto__. JavaScript-, , , . , , null. __proto__ Object.proto-type, , null __proto__:

    var empty = Object.create(null); // ,

    "__proto__" in empty; // false ( )

    __proto__ :

    var empty = Object.create(null); // ,

    "__proto__" in empty; // true ( )

    Object.getPrototypeOf, . , __proto__ - , (.45). , JavaScript-, , - __proto__. -

  • 4 .

    136

    Object.getPrototypeOf, , __proto__ .

    JavaScript-, API-, ES5, __proto__:

    if (typeof Object.getPrototypeOf === "undefined") { Object.getPrototypeOf = function(obj) { var t = typeof obj; if (!obj || (t !== "object" && t !== "function")) { throw new TypeError(" ");

    } return obj.__proto__; };}

    , ES5, , Object.getPrototypeOf .

    Object.getPrototypeOf, __proto__ .

    Object.getPrototypeOf , __proto__ ES5 .

    32 __proto__

    __proto__ - ,

  • 32 . __proto__

    137

    Object.getPrototypeOf, - -. ( , , ?), - . : , - , __proto__.

    , - __proto__, . JavaScript- , , - JavaScript-. , -. , , , -, . __proto__ , , , , , .

    , - __proto__, - . , . - - . - , , - , .

  • 4 .

    138

    - ES5 Object.create. , ES5, Object.create, __proto__ (.33).

    __proto__ .

    Object.create .

    33 , nEw

    , User (.30), , new. , , - :

    function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash;}

    new, :

    var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");

  • 139

    33 . , new

    u; // undefinedthis.name; // "baravelli"this.passwordHash; // "d8b74df393528d51cd19980ae0aa028e"

    undefined, ( , ) name passwordHash.

    User - ES5, undefined:

    function User(name, passwordHash) { "use strict"; this.name = name; this.passwordHash = passwordHash;}var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");// :

    - : User - this.name, TypeError. - , , .

    User . new, , . , - . , User:

    function User(name, passwordHash) { if (!(this instanceof User)) {

  • 4 .

    140

    return new User(name, passwordHash); } this.name = name; this.passwordHash = passwordHash;}

    User , User.prototype , : -:

    var x = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");var y = new User("baravelli", "d8b74df393528d51cd19980ae0aa028e");x instanceof User; // truey instanceof User; // true

    , - . (.21 22) - apply, - . ES5 Object.create:

    function User(name, passwordHash) { var self = this instanceof User ? this : Object.create(User.prototype);

    self.name = name; self.passwordHash = passwordHash; return self;}

    Object.create - - , . , User , , - User.prototype name passwordHash.

  • 141

    33 . , new

    Object.create -, ES5, - new:

    if (typeof Object.create === "undefined") { Object.create = function(prototype) { function C() { } C.prototype = prototype; return new C(); };}

    ( , Object.create, . , - .)

    , - User new? - , . , JavaScript new - , - return. User self, - new self, , this.

    , -, . , - . , - , - new , .

  • 4 .

    142

    , ; new Object.create .

    new, .

    34

    JavaScript . User 30 , :

    function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash; this.toString = function() { return "[User " + this.name + "]"; }; this.checkPassword = function(password) { return hash(password) === this.passwordHash; };}

    - , . User, :

    var u1 = new User(/* ... */);var u2 = new User(/* ... */);var u3 = new User(/* ... */);

    .4.3 , -. -

  • 34 .

    143

    toString checkPassword , , .

    . 4.3. -

    .4.4 , - -. toString checkPassword . , . , , , u3.toString(), toString - ? JavaScript- , - -

  • 4 .

    144

    . - , .

    . 4.4. -

    - , - .

    , - .

    35

    JavaScript - ,

  • 35 .

    145

    . , - , . , for...in ES5 Object.keys() Object.getOwnPropertyNames(), - .

    JavaScript- - , - . , - , - (_). , , , , .

    . , - - , . , , - , - .

    JavaScript - .

    . , - . . , :

  • 4 .

    , - .

    - . , , . User 30:

    function User(name, passwordHash) { this.toString = function() { return "[User " + name + "]"; }; this.checkPassword = function(password) { return hash(password) === passwordHash; };}

    , , toString checkPassword - name passwordHash , this. User , , User.

    , - , , -. 34 , . , , .

    . -

    .

  • 36 . -

    147

    36 -

    -, - . , . , , , . :

    function Tree(x) { this.value = x;}Tree.prototype = { children: [], // // ! addChild: function(x) {

    this.children.push(x); }};

    , , :

    var left = new Tree(2);left.addChild(1);left.addChild(3);

    var right = new Tree(6);right.addChild(5);right.addChild(7);

    var top = new Tree(4);top.addChild(left);

  • 4 .

    148

    top.addChild(right);

    top.children; // [1, 3, 5, 7, left, right]

    addChild Tree.prototype.children, (!) addChild. - Tree, .4.5.

    . 4.5. -

    Tree - children :

    function Tree(x) { this.value = x; this.children = []; //

    }Tree.prototype = { addChild: function(x) {

    this.children.push(x); }};

  • 36 . -

    149

    , , .4.6.

    . 4.6. -

    , , , - . , , , , this. ( , this - , , .) , - . , , , - . , --, . , , -.

  • 4 .

    150

    - , .

    , -, - .

    37 thiS

    CSV (Comma-Separated Values -, ) :

    Bsendorfer,1828,Vienna,Austria

    Fazioli,1981,Sacile,ItalySteinway,1853,New York,USA

    CSV- - . ( , , , "hello, world".) , CSV , . - - , :

    function CSVReader(separators) {

    this.separators = separators || [","]; this.regexp = new RegExp(this.separators.map(function(sep) { return "\\" + sep[0]; }).join("|"));}

  • 37 . this

    151

    read : , . . map:

    CSVReader.prototype.read = function(str) { var lines = str.trim().split(/\n/); return lines.map(function(line) { return line.split(this.regexp); // // ! });};

    var reader = new CSVReader();

    reader.read("a,b,c\nd,e,f\n"); // [["a,b,c"], // ["d,e,f"]]

    , , , - : , , lines.map this, regexp CSVReader. map - lines, . this.regexp undefined, line.split .

    , this , . - 18 25, this, -. , , : , var - . , this - . , this CSVReader.prototype.read this , lines.map.

  • 4 .

    152

    , forEach, - 25, -, map, , , this . , this map:

    CSVReader.prototype.read = function(str) {

    var lines = str.trim().split(/\n/); return lines.map(function(line) { return line.split(this.regexp); }, this); // this //

    };

    var reader = new CSVReader();

    reader.read("a,b,c\nd,e,f\n");// [["a","b","c"], ["d","e","f"]]

    API-, . , map ? - this , - this. : this :

    CSVReader.prototype.read = function(str) {

    var lines = str.trim().split(/\n/); var self = this; // // this

    return lines.map(function(line) { return line.split(self.regexp); // this

  • 37 . this

    });};

    var reader = new CSVReader();

    reader.read("a,b,c\nd,e,f\n");// [["a","b","c"], ["d","e","f"]]

    self, , - this . ( me that.) , .

    ES5 bind, , 25:

    CSVReader.prototype.read = function(str) {

    var lines = str.trim().split(/\n/); return lines.map(function(line) { return line.split(this.regexp); }.bind(this)); // this

    };

    var reader = new CSVReader();

    reader.read("a,b,c\nd,e,f\n");// [["a","b","c"], ["d","e","f"]]

    this .

    this , - , self, me that .

  • 4 .

    154

    38

    (scene graph) , , . - , (actors), - , , (context):

    function Scene(context, width, height, images) { this.context = context; this.width = width; this.height = height; this.images = images; this.actors = [];}

    Scene.prototype.register = function(actor) { this.actors.push(actor);};Scene.prototype.unregister = function(actor) { var i = this.actors.indexOf(actor); if (i >= 0) { this.actors.splice(i, 1); }};

    Scene.prototype.draw = function() { this.context.clearRect(0, 0, this.width, this.height); for (var a = this.actors, i = 0, n = a.length; i < n; i++) { a[i].draw(); }};

  • 38 .

    155

    Actor, . , , - :

    function Actor(scene, x, y) { this.scene = scene; this.x = x; this.y = y; scene.register(this);}

    , moveTo, , :

    Actor.prototype.moveTo = function(x, y) { this.x = x; this.y = y; this.scene.draw();};

    , :

    Actor.prototype.exit = function() { this.scene.unregister(this); this.scene.draw();};

    , . , type, -. , - , ( HTML- Canvas API, - Image - drawImage):

    Actor.prototype.draw = function() { var image = this.scene.images[this.type];

  • 4 .

    156

    this.scene.context.drawImage(image, this.x, this.y);};

    :

    Actor.prototype.width = function() { return this.scene.images[this.type].width;};

    Actor.prototype.height = function() { return this.scene.images[this.type].height;};

    Actor. , (spaceship) SpaceShip, Actor. , SpaceShip -. - SpaceShip , Actor. Actor , :

    function SpaceShip(scene, x, y) { Actor.call(this, scene, x, y); this.points = 0;}

    Actor , Actor. SpaceShip -, .

    SpaceShip Actor, Actor.prototype. ES5 Object.create:

    SpaceShip.prototype = Object.create(Actor.prototype);

    ( 33 Object.create , ES5.)

  • 38 .

    157

    - Space-Ship Actor, . , Actor :

    SpaceShip.prototype = new Actor();

    SpaceShip, -. , SpaceShip x y. SpaceShip, - SpaceShip.prototype. , Actor , SpaceShip. : , - .

    - SpaceShip , -, type - , , :

    SpaceShip.prototype.type = "spaceShip";SpaceShip.prototype.scorePoint = function() { this.points++;};

    SpaceShip.prototype.left = function() { this.moveTo(Math.max(this.x - 10, 0), this.y);};

    SpaceShip.prototype.right = function() { var maxWidth = this.scene.width - this.width(); this.moveTo(Math.min(this.x + 10, maxWidth), this.y);};

  • 4 .

    158

    .4.7 SpaceShip. , scene, x y -, -, - Actor.

    . 4.7.

  • 39 .

    159

    -, this .

    , - Object.create .

    39

    , 38 , . Actor :

    function Actor(scene, x, y) { this.scene = scene; this.x = x; this.y = y; this.id = ++Actor.nextID; scene.register(this);}

    Actor.nextID = 0;

    - Actor, , Alien (), . , :

    function Alien(scene, x, y, direction, speed, strength) { Actor.call(this, scene, x, y);

  • 4 .

    160

    this.direction = direction; this.speed = speed; this.strength = strength; this.damage = 0; this.id = ++Alien.nextID; // // !

    }

    Alien.nextID = 0;

    Alien Actor: - id. ( , - , ), , -, . , , .

    , , , . - Actor Alien :

    function Actor(scene, x, y) { this.scene = scene; this.x = x; this.y = y; this.actorID = ++Actor.nextID; // // alienID

    scene.register(this);}

    Actor.nextID = 0;

    function Alien(scene, x, y, direction, speed, strength) {

  • 40 .

    161

    Actor.call(this, scene, x, y); this.direction = direction; this.speed = speed; this.strength = strength; this.damage = 0; this.alienID = ++Alien.nextID; // // actorID

    }

    Alien.nextID = 0;

    , .

    - .

    40

    ECMAScript -, , Array, Function Date. - , , , , .

    Array . , :

    function Dir(path, entries) { this.path = path;

  • 4 .

    162

    for (var i = 0, n = entries.length; i < n; i++) { this[i] = entries[i]; }}

    Dir.prototype = Object.create(Array.prototype);// Array

    , length :

    var dir = new Dir("/tmp/mysite", ["index.html", "script.js", "style.css"]);dir.length; // 0

    , length - , . ECMAScript - [[Class]]. -, JavaScript . [[Class]] : ( Array []) - "Array" [[Class]], "Function" [[Class]] .. [[Class]], - ECMAScript, .4.1.

    , [[Class]] length? , length , [[Class]] Array. length . - , length - , length, , , .

  • 40 .

    163

    4.1. [[Class]], ECMAScript

    [[claSS]]

    "Array" new Array(...), [...]

    "Boolean" new Boolean(...)

    "Date" new Date(...)

    "Error" new Error(...), new EvalError(...), new RangeError(...), new ReferenceError(...), new SyntaxError(...), new TypeError(...), new URIError(...)

    "Function" new Function(...), function(...) {...}

    "JSON" JSON

    "Math" Math

    "Number" new Number(...)

    "Object" new Object(...), {...}, new MyClass(...)

    "RegExp" new RegExp (...), /.../

    "String" new String (...)

    Array, - new Array() []. Dir [[Class]] "Object". : Object.prototype.toString [[Class]] , :

    var dir = new Dir("/", []);Object.prototype.toString.call(dir); // "[object Object]"Object.prototype.toString.call([]); // "[objectArray]"

    Dir - length, .

    - :

  • 4 .

    function Dir(path, entries) { this.path = path; this.entries = entries; //

    }

    Array - entries:

    Dir.prototype.forEach = function(f, thisArg) { if (typeof thisArg === "undefined") { thisArg = this; } this.entries.forEach(f, thisArg);};

    ECMAScript , [[Class]] , -. : Array, Boolean, Date, Function, Number, RegExp String.

    - , [[Class]] .

    , .

    41

    , .

  • 41 .

    165

    . , . , - , , . : .

    JavaScript - (introspection) . Object.prototype.hasOwnProperty -, ( ), -. Object.getPrototypeOf __proto__ (.30) -. .

    , . , , . , -, , . , : - , ( ) .

    , JavaScript (.35). -. , - , .

  • 4 .

    166

    , . ,

    .

    , , .

    42

    41 . - , , , . (monkey-patching).

    . ? :

    Array.prototype.split = function(i) { // 1

    return [this.slice(0, i), this.slice(i)];};

    : split.

    - , . ,