Вы находитесь на странице: 1из 265

JavaScript.

JavaScript . , ,
C++ Java,
, JavaScript. JavaScript
.
:

JavaScript,
,
var

JavaScript

,
-

JavaScript

JavaScript :
(singleton), (factory), (decorator)

, ,

. , .

JavaScript.

, JavaScript
, , , . JavaScript
? , JavaScript. ,
,
.

JavaScript

(Stoyan Stefanov) - Yahoo!, , , OReilly.


smush.it
YSlow 2.0 Yahoo.

ISBN 978-5-93286-208-7

9 785932 862087

JavaScript .indd 1

-
(812) 380-5007, (495) 638-5305

www.symbol.ru

:
:

24.03.2011 14:08:18

- -
Books.Ru
ISBN 978-5-93286-208-7,
JavaScript. - Books.Ru
. -
, .
,
- (piracy@symbol.ru),
.

JavaScript
Patterns
Stoyan Stefanov

JavaScript

-
2011

JavaScript.
.

.
.
.

.

.

.

.
.
JavaScript. . . . .: -, 2011. 272., .
ISBN 978-5-93286-208-7
, Java
Script , , , .
JavaScript ?
,
JavaScript,
(singleton), (factory), (decorator) . ,
, .
JavaScript
. , , C++ Java, , JavaScript.
JavaScript .
JavaScript
Yahoo! - YSlow 2.0, . , .
ISBN 978-5-93286-208-7
ISBN 978-0-596-80675-0 ()
-, 2011
Authorized translation of the English edition 2010 OReilly Media Inc.. This trans
lation is published and sold by permission of OReilly Media Inc., the owner of all rights
to publish and sell the same.
,
.
, , .

-.199034,-,16,7,
.(812) 380-5007, www.symbol.ru. N 000054 25.12.98.
23.03.2011. 70100 1/16. .
17 .. 1500 .

199034, -, 9 , 12.

,
,


.............................................................................. 13
1. .......................................................................19
..................................................................................19
JavaScript: ................................................................ 21
JavaScript - ........................... 21
JavaScript .............................................. 22
............................................................................ 23
................................................................. 23
ECMAScript5........................................................................... 24
JSLint...................................................................................... 25
.................................................................................... 26

2. ......................................................................... 28
.............. 28
..................... 30
, ................... 30
, var...... 32
................................................. 33
var...................................... 33
: ..................... 34
for................................................................................ 36
for-in............................................................................ 38


( )....................................................... 41
switch.......................................................................... 42
........................................ 42
eval()............................................................. 43


parseInt()................................................................. 45
.......................... 46
............................................................................... 46
................................................................... 47

..................................... 48
............................................................................... 49
....................................................... 51
............................. 51
..................................................................... 51
.................................................. 52
............................................................................ 53
API............................................................. 54
YUIDoc................................................ 55
, ....................................... 59
..................................................................... 60
.................................... 60
JSLint........................................................................... 61
........................................................................... 62

3. ........................................... 64
................................................................... 64
................................................66
............................66
Object.............................................. 67
-.......................................... 68
, ................................69
new........................... 70
.................................................... 71
that..................................................... 71
, .................................... 72
................................................................... 73
................................................ 73
Array............................................... 73
................................................................. 74
JSON........................................................................................ 75
JSON........................................... 76
............................................. 77
........................... 77
- .................................. 79
Error.......................................................................... 80
........................................................................... 81

4. ....................................................................... 83
..................................................................................... 83
........................... 85
: ................................ 86

name .......................................................... 87
................................................................... 88
........................................................ 89
..................... 90
.................... 92
......................................... 94
................................................... 94
.................................95
.............................................................. 95
...................................................... 96
............................................. 98
...........................99
,
.................................................... 100
........................... 101
.................................... 102
, .... 104
.................................. 106
........................................................... 108
......................................................................... 109
........................................................... 109
......................................................... 110
..................................................................... 112
.......................................... 115
......................................................................... 115

5. .................................... 117
...................................................................117
......... 119
........................................................ 121
...................................................... 123
.................................................................... 123
.................................................. 124
............................... 124
...................................... 126
.................................................. 126
........ 127
.................................................................... 129
..................................................... 131
, ......................................... 132
................. 133
.............................. 133

10

...................................................... 134
............................................................. 135
..................................................... 136
.................................................................. 138
........................................ 138
.................................................. 140
-................................................................ 142
...................................................................... 144
............................ 145
method()....................................................................... 145
..........................................................................147

6.
................................................................. 148
................. 149

.................................................... 150
1: ...................... 150
.................................................... 151
1....................................................... 153
2: ............ 154
............................................................. 155

......................................... 157

................................................. 157

3:
...................................... 158
4:
........................................ 159
5: ................... 160
....................................................... 162
...................................... 162
klass()...................................................................... 163
................................................... 166
........................................................................ 168
ECMAScript5.................................... 169
........................................ 169
............................................................................171
............................................................173
: ................................. 173
................................................. 174

11
Function.prototype.bind()...................................................... 176

..........................................................................176

7. ........................................ 178
...............................................................178
new................................................ 179
......................................... 180
....................................................... 181
................................................................................. 184
................................................ 186
................................................................................ 187
............................................................................... 189
......................................................... 189
......................................................................... 190
..................................... 193
............................................................................... 194
..................................................... 195
..................................................................................... 198
-........................................................................ 199
.............................................................................. 200
- ........................................................ 209
.............................................................................. 209
........................... 210
.......................................................................... 213
1: .............................................. 214
2: ........................................ 217
......................................................................... 221

8. DOM
........................................................................... 223
................................................. 223
DOM.............................................................. 225
DOM............................................................ 225
DOM............................................ 227
................................................................................. 228
............................................................... 229
........................................................ 231
, ........................ 233
setTimeout()........................................................................ 233
(web workers)........................................ 234
...................................................... 235
XMLHttpRequest................................................................. 235

12

JSONP.................................................................... 237
....... 240
JavaScript........................................ 241
........................................................ 241
........................................................... 242
Expires................................................................ 243
CDN............................................................. 243
................................................................. 244
<script>........................................ 244
HTTP..................................... 246
<script>
.............................................................. 247
........................................................... 249
........................................................ 250
JavaScript...................... 252
......................................................................... 254

........................................................... 256


-. , ,
.
, , ,
.
, .


,
JavaScript .
JavaScript ( ,
) .
,
.
( ) ;
, ,
.
, JavaScript, .

,
URL
, , .

14


,
,
, , , , .

,
.

, , .
,
.


.

.
, . ,

, . -

OReilly.
.

.
,
. , ISBN. : JavaScript Patterns, by
Stoyan Stefanov (OReilly). Copyright 2010 Yahoo!, Inc., 9780596806750.


permissions@oreilly.com.

15

Safari Books Online


Safari Books Online ,
7500
.
,
. . , . , .
,
, ,
, , ,
.
OReilly Media
Safari

Books

Online
. ,
OReilly , http://
my.safaribooksonline.com.


, , :
OReilly Media
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 ( )
707-829-0515 ()
707-829-0104 ()
, :
http://www.oreilly.com/catalog/9780596806750/

:
bookquestions@oreilly.com
, ,
OReilly :
http://www.oreilly.com

16

, , .

,
.
(Dmitry Soshnikov) (http://dmitrysoshnikov.com,
@DmitrySoshnikov)
(Andrea Giammarchi) (http://webreflection.blog
spot.com, @WebReflection)
(Asen Bozhilov) (http://asenbozhilov.com, @abozhilov)
(Juriy Zaytsev) (http://perfectionkills.com, @kangax)
(Ryan Grove) (http://wonko.com, @yaypie)
(Nicholas Zakas) (http://nczonline.net, @slicknet)
(Remy Sharp) (http://remysharp.com, @rem)
(Iliyan Peychev)

, ,
Java
Script
,
jQuery

YUI
. Java

Script
. .
,
http://www.jspatterns.com/book/reading/.
,
,
, http://jspatterns.
com.


,
, .
JavaScript,
:
Object-Oriented JavaScript (Stoyan Stefanov) (Packt
Publishing)

17

JavaScript: The Definitive Guide, (David Flanagan)


(OReilly)1
JavaScript: The Good Parts, (Douglas Crockford)
(OReilly)
Pro JavaScript Design Patterns, (Ross Hermes)
(Dustin Diaz) (Apress)
High Performance JavaScript, (Nicholas Zakas)
(OReilly)2
Professional JavaScript for Web Developers,

(Nicholas Zakas) (Wrox)


(Stoyan Stefanov) - Yahoo!,

Object-Oriented JavaScript,

Even Faster Web Sites High Performance JavaScript,


JavaScript: The Good Parts PHP Mashups.

,
JavaScript
,
PHP
-, (http://www.phpied.com). smush.it

YSlow
2.0 Yahoo.

JavaScript. , 5- . .
. .: -, 2008.

JavaScript. . .
. .: -, III 2011.

JavaScript .
- ( ),
. , , JavaScript
. (
.NET Node.js), (
) (,
Firefox Photoshop),
.
JavaScript .
, , .
,
. , , Java PHP,
JavaScript, ,
JavaScript .
JavaScript
, .
JavaScript .

20

1.

(http://ru.wikipedia.
org/wiki/Pattern).
. , .
, .
, :
, .
,
,
(
).
,
.
, . , ( ) (immediate function), , , ,
.
:



( ) , 1994
Design Patterns: Elements of Reusable Object-Oriented
Software1. , singleton (), factory (), decorator
(), observer () .

JavaScript , ,
,

. , . , . , . -
. . . , 2001.

JavaScript:

21

, C++ Java.
, JavaScript.
,
.
JavaScript . JavaScript 7 .
, , , JavaScript , . JavaScript
.
.
, .
, ,
, .
.

JavaScript:
, .

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

, : , , , null undefined,
- (
). ,
, JavaScript.
.
.

. JavaScript, ,
. -,
, (Activation Object) ( ,
). -,

22

1.

,
( ), , for-in. ECMAScript 3, 5
.
? , - . . , - (
). ( ), .
,
. (,
ECMAScript 5 API, .) ,
. , ,
, ,
.
, , :

ECMAScript.

(, ).
(, Array, Date) (var o = {};).
, window DOM. ,
, , . , , .

JavaScript

: JavaScript .
,
, ,
.

JavaScript:

23


, .
, Java:
// Java
HelloOO hello_oo = new HelloOO();

,
.
, .
JavaScript , .
,
. ; , . .
, , : , . ,
, , , . JavaScript
, , , , , .

JavaScript ,
.
( .)
,
. ( ), prototype, .
, Object(), ,
constructor
, Object(). ,
.
,
, ( - ) prototype.


JavaScript, . JavaScript -

24

1.

, . ,
, JavaScript (ECMAScript),
.
:
, , 8.
, .

, ECMAScript
.

ECMAScript5
JavaScript ( DOM, BOM
) ECMA
Script, ES. 3 1999
. 4
, 2009 , 10
, 5.
5 ,
, (strict) , , . with,
. , ES5,
,
. , . , , .
( ,
, eval()) , :
function my() {
use strict;
// ...
}

,
. , -

25

JSLint

, .
,
. ES5
,
, .
, , ES5,

ES5. ,
, :

, argu
ments.callee
ES3, ES5
, Object.create()

JSLint
JavaScript , .
, , .
,
JSLint (http://jslint.com).
JSLint Java
Script, (Douglas Crockford),
.
JSLint. , , . JSLint

JavaScript.
JSLint , ,
.
, JSLint.
JSLint ( ,
, ),
, .

26

1.

JSLint , .

console.
. Firefox,
, Firebug.
Firebug ,
JavaScript
(.1.1).
, Firebug .
, WebKit (Safari Chrome), Web Inspector, IE, 8,
Developer Tools.

.1.1. Firebug


alert() console,
.
log(), , dir(), -

27

. :
console.log(test, 1, {}, [1,2,3]);
console.dir({one: 1, two: {three: 3}});

console.log()
. ,
, ,
:
window.name === window[name]; // true

:
console.log(window.name === window[name]);

true.

,
JavaScript,
,
var,
, . , ,
,
,
JSLint.
, ,
( ) .



.
,
.
, ,
, . ,
, .
:
,
, ,

29

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



(, , )

,
,
,
-, -, .
.

:



,

, , Java
Script.

30

2.

JavaScript
. , ,
.
, ,
, .
JavaScript ,
this .

. window, ()
. ,
:
myglobal = hello;
console.log(myglobal);
console.log(window.myglobal);
console.log(window[myglobal]);
console.log(this.myglobal);

//
//
//
//
//

hello
hello
hello
hello

,
, , ,
JavaScript -
.
,

, .
, - , , :
JavaScript


,
,
, , result. , result.

result,
.

, ,
.

31

,
,
, ,
var.
Java
Script . -,
. -
,
, ( ,
). :
function sum(x, y) {
// :
result = x + y;
return result;
}

result.
, result,
.
,
var, sum():
function sum(x, y) {
var result = x + y;
return result;
}

, ,
var.
a, b ,
, , :
// ,
function foo() {
var a = b = 0;
// ...
}

, , -
, . b = 0, b . 0,
, -

32

2.

var a. , :
var a = (b = 0);

,
. :
function foo() {
var a, b;
// ...
a = b = 0; //
}
. , , , - ,
,
(- , ,
), - .

,
var

, ,
delete :
,
var ( , - ),
.
,
var ( ,
), .
, ,
. delete, :
//
var global_var = 1;
global_novar = 2;
//
(function () {
global_fromfunc = 3; //
}());

33

//
delete global_var;
// false
delete global_novar;
// true
delete global_fromfunc; // true
//
typeof global_var;
// number
typeof global_novar;
// undefined
typeof global_fromfunc; // undefined

, ES5, (
) .



window ( -
, ,
window).
( ). window,
:
var global = (function () {
return this;
}());


, , ( new), this
. , ECMA
Script 5, ,
. , ,
(
4),
this .

var
var
, . :
, ,
,

34

2.

,
, (
)

(
)
var :
function func() {
var a = 1,
b = 2,
sum = a + b,
myobject = {},
i,
j;
// ...
}

var
, .
. ( undefined),
. , ,
,
. ,
.
, , sum =
a + b . : DOM
(Document Object Model ), , :
function updateElement() {
var el = document.getElementById(result),
style = el.style;
// el style...
}

:
JavaScript var
, , -

35

.
(hoisting) ,
,
. JavaScript ,
( ),
var,
. :
//
myname = global;
//
function func() {
alert(myname);
// undefined
var myname = local;
alert(myname);
// local
}
func();

, alert()
global, local. , alert() myname
, , ,
myname. .
alert() undefined, myname .
( , .)
. ,
,
, , .
, ,
:
myname = global;
function func() {
var myname;
alert(myname);
myname = local;
alert(myname);
}
func();

//
// , -> var myname = undefined;
// undefined
// local

, .
, ,

,
. ,
, - ( ).
-

36

2.
(hoisting),
ECMAScript,
.

for
for , , arguments HTML
Collection.
for:
//
for (var i = 0; i < myarray.length; i++) {
// - myarray[i]
}

, . ,
myarray , HTMLCollection.
HTMLCollection , DOM, :
document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()
HTMLCollection,
DOM - .
( ) :
document.images
IMG .
document.links
A.
document.forms
.
document.forms[0].elements
.
, ( HTML-).
, DOM, DOM, , .
for ( ) , :

37

for
for (var i = 0, max = myarray.length; i < max; i++) {
// - myarray[i]
}

length
.
HTMLCollections (Safari 3) 190 (IE7). ( High Performance JavaScript1, (Nicholas Zakas) [OReilly].)
, , (, DOM), ,
, .
var, var
, :
function looper() {
var i = 0,
max,
myarray = [];
// ...
for (i = 0, max = myarray.length; i < max; i++) {
// - myarray[i]
}
}


var.
,
. , i max (, ,
, ).
for i++ :
i = i + 1
i += 1

JSLint . ,
++ -- . 1

. JavaScript. . . .
.: -. III 2011 .

38

2.

, JSLint plusplus
false. ( true.)

: i += 1.

for, :
(
max).
,
- , 0 ,
, 0.
:
var i, myarray = [];
for (i = myarray.length; i--;) {
// - myarray[i]
}

, while:
var myarray = [],
i = myarray.length;
while (i--) {
// - myarray[i]
}

, , , . , JSLint i--.

for-in
for-in ,
. for-in
.
for-in
( JavaScript
), . , . ,
for-in - .
for,
for-in .

for-in

39

hasOwn
Property(), ,
.
:
//
var man = {
hands: 2,
legs: 2,
heads: 1
};
// -
//
if (typeof Object.prototype.clone === undefined) {
Object.prototype.clone = function () {};
}

man,
. - ,
man, Object clone().
, , .
clone()
man, hasOwnProperty(),
. , clone() , :
// 1.
// for-in
for (var i in man) {
if (man.hasOwnProperty(i)) { //
console.log(i, :, man[i]);
}
}
/*

hands : 2
legs : 2
heads : 1
*/
// 2.
// :
// for-in hasOwnProperty()
for (var i in man) {
console.log(i, :, man[i]);
}

40

2.
/*

hands : 2
legs : 2
heads : 1
clone: function()
*/

hasOwnProperty() Object.prototype, :
for (var i in man) {
if (Object.prototype.hasOwnProperty.call(man, i)) { //
console.log(i, :, man[i]);
}
}

,
, man has
OwnProperty. ,
Object,
:
var i,
hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
if (hasOwn.call(man, i)) { //
console.log(i, :, man[i]);
}
}
, hasOwnProperty()
.

. ( , ), hasOwn
Property().

( JSLint)

if for.
(
, X , ). , :
// : JSLint
var i,

( )

41

hasOwn = Object.prototype.hasOwnProperty;
for (i in man) if (hasOwn.call(man, i)) { //
console.log(i, :, man[i]);
}


( )
prototype -
, .
, Object(), Array() Function(),
,
. , , ,
JavaScript ,
. , ,
, , hasOwnProperty(), .
.
:
1. , ECMAScript JavaScript
. , ,
ECMAScript5,
.
.
2. , -
JavaScript
, .
3. .
,
, :
if (typeof Object.protoype.myMethod !== function) {
Object.protoype.myMethod = function () {
// ...
};
}

42

2.

switch
,
switch :
var inspect_me = 0,
result = ;
switch (inspect_me) {
case 0:
result = zero;
break;
case 1:
result = one;
break;
default:
result = unknown;
}


:
case switch ( ).
case
.
case
break;.

case ( break).
, , ,
case , , ,
break .
switch default:,
- case.


JavaScript .
, false == 0 == 0, true.
, ,
=== !==, , , :

43

var zero = 0;
if (zero === false) {
// ,
// zero 0, false
}
//
if (zero == false) {
//
}

, , ==, ===
. , typeof,
, , . JSLint
. (
: ==
?)

eval()
eval() ,
eval() . JavaScript.
, ( ),
eval().
,
eval(). , :
//
var property = name;
alert(eval(obj. + property));
//
var property = name;
alert(obj[property]);

, eval()
,
(, ),
. JSON, Ajax.
JSON
, .

44

2.

, JSON.
parse(), , JSON.org.
, setInterval(), set
Timeout() Function() eval(),
. JavaScript :
//
setTimeout(myFunc(), 1000);
setTimeout(myFunc(1, 2, 3), 1000);
//
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);

new Function()
eval(), . ,
. eval(), new Function(). ,
, new Func
tion(), ,
, var,
.
, eval() (
4).
. un
:
console.log(typeof un);
console.log(typeof deux);
console.log(typeof trois);

// undefined
// undefined
// undefined

var jsstring = var un = 1; console.log(un);;


eval(jsstring);
// 1
jsstring = var deux = 2; console.log(deux);;
new Function(jsstring)();
// 2
jsstring = var trois = 3; console.log(trois);;
(function () {
eval(jsstring);

45

parseInt()
}());

// 3

console.log(typeof un);
console.log(typeof deux);
console.log(typeof trois);

// number
// undefined
// undefined

eval() Function ,
eval() ,
Function . , Function, . .
eval()
, Function ( , Function()
new Function()):
(function () {
var local = 1;
eval(local = 3; console.log(local));
console.log(local);
}());

// 3
// 3

(function () {
var local = 1;
Function(console.log(typeof local);)(); // undefined
}());


parseInt()
parseInt() . , , . , 0, , ,
. ECMAScript 3, , 0, (
8). ES5.
, , :
var month = 06,
year = 09;
month = parseInt(month, 10);
year = parseInt(year, 10);

, parseInt(year)
0, 09 (

46

2.

parseInt(year, 8)), 9
.
:
+08
// : 8
Number(08) // 8

, parseInt(),
parseInt(), ,
, . , 08 hello, parseInt()
, NaN.



,
. , ,
,
, .

(,
?).
, , ,
. , , , ,
.

.
, , , .
.
,
, .
. , , ,
.

47

, , . JSLint.
? , . , (do, while, for, for-in), if,
switch . :
function outer(a, b) {
var c = 1,
d = 2,
inner;
if (a > b) {
inner = function () {
return {
r: c - d
};
};
} else {
inner = function () {
return {
r: c + d
};
};
}
return inner;
}


,
. , if
for ,
, ,
.
.
, for, . ,
:
//
for (var i = 0; i < 10; i += 1)
alert(i);


?
//
for (var i = 0; i < 10; i += 1)

48

2.
alert(i);
alert(i + is + (i % 2 ? odd : even));

alert() ,
.
, :
//
for (var i = 0; i < 10; i += 1) {
alert(i);
}

if:
//
if (true)
alert(1);
else
alert(2);
//
if (true) {
alert(1);
} else {
alert(2);
}


, , , .
if (true) {
alert(Its TRUE!);
}

:
if (true)
{
alert(Its TRUE!);
}


,
, . JavaScript
; .

49

, , , ,
:
// :
function func() {
return
{
name: Batman
};
}

, name,
. - return , undefined. ,
:
// :
function func() {
return undefined;
// ...
{
name: Batman
};
}

:
function func() {
return {
name: Batman
};
}
: , , ,
JavaScript.
,
, .

.
. JavaScript
( ) -

50

2.

( , ).
:
, for, :
for (var i = 0; i < 10; i += 1) {...}
(i max) for:
for (var i = 0, max = 10; i < max; i += 1) {...}
, : var a = [1, 2, 3];
, , , : var o = {a: 1, b: 2};
, : myFunc(a, b, c)
:
function myFunc() {}
function : var myFunc = function () {};
,
+, -, *, =, <, >, <=, >=, ===, !==, &&, ||,
+= :
//
// ,
//
var d = 0,
a = b + 1;
if (a && b && c) {
d = a % c;
a += d;
}
//
//
//
var d= 0,
a =b+1;
if (a&& b&&c) {
d=a %c;
a+= d;
}

, :
:
({) , if-else, switch, .
(}) else
while.

51

, ( ).
, , . , .


, .
, ,
, .
,
, .


JavaScript , , new:
var adam = new Person();

,
, , , , .
.
, ,
new:
function MyConstructor() {...}
function myFunction() {...}

, ; , ,
.


,
, -

52

2.

.
(camel case).
,
.

( ), MyConstructor().

( ), myFunction(), calculateArea() get
FirstName().
, ?
( ),
, , first_name, favorite_bands old_company_name. .
ECMAScript , , ,
( lastIndex ignoreCase
).



.
, JavaScript ( ,
Number.MAX_VALUE), ,
, , :
// ,
var PI = 3.14,
MAX_WIDTH = 800;

,
,
.
.
.
JavaScript , , -

53

,
. :
var person = {
getName: function () {
return this._getFirst() + + this._getLast();
},
_getFirst: function () {
// ...
},
_getLast: function () {
// ...
}
};

, getName()
, API, _getFirst()
_getLast() . , person,
. , JSLint , , nomen: false.
_private:

, name_ getElements_()
( _protected),
( __private)
Firefox ,
. ,
__proto__ __parent__

,
, . , , ,
, , .
: . , ,

54

2.

. ,
,
, ,
. , ,
, ,
, ,
,
. , ; ( )
, .
,
, , , .

, , , .

API

.
.
(API) .
, .
,
.

API Java, javadoc, Java SDK (Software Developer Kit ).
. JavaScript
, : JSDoc Toolkit (http://code.google.com/p/
jsdoc-toolkit/) YUIDoc (http://yuilibrary.com/projects/yuidoc).
API :

,

, HTML

API

55

, ,
:
/**
* @tag value
*/

, , reverse(),
. . :
/**
* Reverse a string
*
* @param {String} input String to reverse
* @return {String} The reversed string
*/
var reverse = function (input) {
// ...
return output;
};

@param , @return . , ,

HTML.

YUIDoc
YUIDoc YUI (Yahoo! User Interface Yahoo!),
. , , , , . ( , JavaScript .)

YUIDoc.
.2.1 , , . HTML, .

http://jspatterns.com/book/2/.
(app.js)
(myapp) . , , YUIDoc.

56

2.

.2.1. , YUIDoc

app.js :
/**
* My JavaScript application
*
* @module myapp
*/

, :
var MYAPP = {};

math_stuff, :
sum() multi():
/**
* A math utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {

API

57

/**
* Sums two numbers
*
* @method sum
* @param {Number} a First number
* @param {Number} b The second number
* @return {Number} The sum of the two inputs
*/
sum: function (a, b) {
return a + b;
},
/**
* Multiplies two numbers
*
* @method multi
* @param {Number} a First number
* @param {Number} b The second number
* @return {Number} The two inputs multiplied
*/
multi: function (a, b) {
return a * b;
}
};

. :
@namespace
.
@class
( JavaScript ), -.
@method
.
@param
, .
,
.
@return
@param, , , .
-, .
, , ,
:

58

2.
/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} first First name
* @param {String} last Last name
*/
MYAPP.Person = function (first, last) {
/**
* Name of the person
* @property first_name
* @type String
*/
this.first_name = first;
/**
* Last (family) name of the person
* @property last_name
* @type String
*/
this.last_name = last;
};
/**
* Returns the name of the person object
*
* @method getName
* @return {String} The name of the person
*/
MYAPP.Person.prototype.getName = function () {
return this.first_name + + this.last_name;
};

Person, .2.1. :
@constructor , -
@property @type
YUIDoc

JavaScript.
,
, @property first_name. , ,
.

59

,
API ;
, .
,
: , , . . ,
.
.
- , , . , ? , , ? ,
,
, ,
. , , ,
.
(
), , , . API
.

. , , , , true,
, .
, , , , API, ,
- .

.
, , , , .
, ,
( ). ,

60

2.

, .
, , . ,
.
; .



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

(CVS, Subversion Git),
.
, , -
, .


, JavaScript
,
. -

JSLint

61

(),
Yahoo! YUICompressor Google Closure Compiler, .
,
,
.
,
( Event YUI2 ):
YAHOO.util.CustomEvent=function(D,C,B,A){this.type=D;thisscope=C||window;this.
silent=B;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if
(!this.silent){}varE=_YUICEOnSubscribe;if(D!==E){this.subscribeEvent=new
YAHOO.util.CustomEvent(E,this,true);}...

, , (
), , , D, C, B, A
. ,
.
,
.
, DOM, ,
.
,
,
.
, Google Closure Compiler (
),
.

,
, . . ,
, , . , ,
(), ,
, , ().

JSLint
JSLint
. , .

62

2.

JSLint ? ,
( var,
parseInt(),
), , :
,

UTF
void, with eval

JSLint JavaScript (
JSLint). ,
-
JavaScript.
, WSH
(Windows Scripting Host Windows
, Windows),
JSC (JavaScriptCore, Mac OSX)
Rhino ( JavaScript, Mozilla).
JSLint
,
. ( JSLint .)


,
.
,
, . , :
,
.
var ,
,
.
for, for-in, switch, eval() , .
( ;

63

,
) (,
).
,
, ,
, ,
API,
,

JSLint.


,
JavaScript, ,
.
, , ,
, Object() Array().
JSON
, . ,
new
.
( , )
- Number(), String() Boolean() , .
Error().


Java

Script
-, - ( ,
).
. ,
, .

65

, ( ,
, ), .
.
, .

.
:
//
var dog = {};
//
dog.name = Benji;
//
dog.getName = function () {
return dog.name;
};

,
. .
:
, :
dog.getName = function () {
// ,
//
return Fido;
};

:
delete dog.name;

:
dog.say = function () {
return Woof!;
};
dog.fleas = true;

. , .
var dog = {
name: Benji,
getName: function () {
return this.name;
}
};

66

3.


. , , JavaScript .
{} , Object.prototype. , , .



, .
, .
:
{ }.
. -
,
IE
, .
.

}.



JavaScript
, , ,
. JavaScript -,
,
- , Java.
, , Object(), Date(),
String() .

:
// --
var car = {goes: far};
// --
// :
var car = new Object();
car.goes = far;

67

. , ,
, ,
, ,
,
( ).

Object()
. ,
Object(),
Object().

Object
new Object(),
,
, , ( ). , Object()
, , .
, new Object(). , :
// :
//
var o = new Object();
console.log(o.constructor === Object);

// true

// -
var o = new Object(1);
console.log(o.constructor === Number);
console.log(o.toFixed(2));

// true
// 1.00

// -
var o = new Object(I am a string);
console.log(o.constructor === String);

// true

// substring()
// -
console.log(typeof o.substring);
// function

68

3.
//
var o = new Object(true);
console.log(o.constructor === Boolean); // true

Object() , , , . new Object(). .

-
-
-
, :
var adam = new Person(Adam);
adam.say();
// I am Adam

Java
Person. , JavaScript , Person
.
-
Person.
var Person = function (name) {
this.name = name;
this.say = function () {
return I am + this.name;
};
};

- new
:
, , this.
this.
,
this ( ).
, :
var Person = function (name) {
//
//
// var this = {};

69

//
this.name = name;
this.say = function () {
return I am + this.name;
};
// return this;
};

say() this. new Person()


. , ,
say() .
Person:
Person.prototype.say = function () {
return I am + this.name;
};

,
, , ,
, .
-
. , , ,
:
// var this = {};

,
Person. :
// var this = Object.create(Person.prototype);

Object.create() .

,
new -
. , this.
,
(, , ).
this, return.
. , that.

70

3.
var Objectmaker = function () {
// `name` ,
//
//
this.name = This is it;
//
var that = {};
that.name = And thats that;
return that;
};
//
var o = new Objectmaker();
console.log(o.name); // And thats that

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

new
, , new. ,
new ?
, .
new, this
. ( this window.)
- ,
this.member, new member , : window.member member.
,
.
//
function Waffle() {
this.tastes = yummy;
}
//
var good_morning = new Waffle();

new

71

console.log(typeof good_morning); // object


console.log(good_morning.tastes); // yummy
// :
// `new`
var good_morning = Waffle();
console.log(typeof good_morning); // undefined
console.log(window.tastes);
// yummy

ECMAScript 5,
this .
ES
5 , , -
, new.


,
,
(MyConstructor), (myFunction).

that
, , , , . , ,
.
, this that
.
function Waffle() {
var that = {};
that.tastes = yummy;
return that;
}


, that , ,
:
function Waffle() {
return {
tastes: yummy
};
}

Waffle() , :

72

3.
var first = new Waffle(),
second = Waffle();
console.log(first.tastes); // yummy
console.log(second.tastes); // yummy

,
, ,
Waffle(), .
, that
.
. self me.

,
, ,
,
.
, this ,
, , new:
function Waffle() {
if (!(this instanceof Waffle)) {
return new Waffle();
}
this.tastes = yummy;
}
Waffle.prototype.wantAnother = true;
//
var first = new Waffle(),
second = Waffle();
console.log(first.tastes);
console.log(second.tastes);

// yummy
// yummy

console.log(first.wantAnother); // true
console.log(second.wantAnother); // true

,
,
arguments.callee.
if (!(this instanceof arguments.callee)) {
return new arguments.callee();
}

73

,
arguments,
, . arguments callee, .
, arguments.callee ES5, ,
,
.


, Java

Script
, .
Array(), . , .

Array() .
//
// :
var a = new Array(itsy, bitsy, spider);
//
var a = [itsy, bitsy, spider];
console.log(typeof a); // object, -
console.log(a.constructor === Array); // true


: , , .
, .
. ,
, . ( ) new.

Array
,
new Array(), ,
.

74

3.

Array() , .

. new Array(3) , 3, .
, undefined,
. ,
.
//
var a = [3];
console.log(a.length);
// 1
console.log(a[0]);
// 3
//
var a = new Array(3);
console.log(a.length);
// 3
console.log(typeof a[0]); // undefined

, , new Array() ,
.
, :
//
var a = [3.14];
console.log(a[0]); // 3.14
var a = new Array(3.14); // RangeError:
console.log(typeof a); // undefined


, .
, Array() , .
, 255 (
256, ):
var white = new Array(256).join( );


typeof
object.
console.log(typeof [1, 2]); // object

- ( ), .

75

JSON

, . , length ,
, slice().
, , , ,
. instanceof
Array, IE.
ECMAScript5 Array.isArray(), true, . :
Array.isArray([]); // true
//
// ,
Array.isArray({
length: 1,
0: 1,
slice: function () {}
});
// false

, Object.prototype.toString(). call() toString ,


[object Array].
[
object

Object
]. , , :
if (typeof Array.isArray === undefined) {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === [object Array];
};
}

JSON
, , ,
JSON
, Java

Script
Object

Nota
tion
( JavaScript). JavaScript.
JSON

. .
JSON:
{name: value, some: [1, 2, 3]}

, JSON

, .

76

3.

, , , : {first name: Dave}.



JSON
.

JSON
, - ,
,
JSON eval(). JSON.parse(), ,
ES
5, Java

Script
. JSON JSON.org (http://
www.json.org/json2.js).
// JSON
var jstr = {mykey: my value};
//
var data = eval(( + jstr + ));
//
var data = JSON.parse(jstr);
console.log(data.mykey); // my value

Java

Script
, ,
JSON
, JSON

.
org
. , YUI3 :
// JSON
var jstr = {mykey: my value};
//
// YUI
YUI().use(json-parse, function (Y) {
var data = Y.JSON.parse(jstr);
console.log(data.mykey); // my value
});

jQuery parseJSON():
// JSON
var jstr = {mykey: my value};
var data = jQuery.parseJSON(jstr);
console.log(data.mykey); // my value

77

JSON.stringify() ,
JSON.parse().

( ) JSON.
var dog = {
name: Fido,
dob: new Date(),
legs: [1, 2, 3, 4]
};
var jsonstr = JSON.stringify(dog);
// jsonstr:
// {name:Fido,dob:2010-04-11T22:36:22.436Z,legs:[1,2,3,4]}


JavaScript ,
:
new RegExp()


, :
//
var re = /\\/gm;
//
var re = new RegExp(\\\\, gm);

,
. .
, RegExp() ,
, , .

. , , ,
.


,
, .

78

3.

:
g
m
i

:
var re = /pattern/gmi;


, String.
prototype.replace(), .
var no_letters = abc123XYZ.replace(/[a-z]/gi, );
console.log(no_letters); // 123

,
RegExp(),
.

,
. ,
( lastIndex),
. , ,
.
function getRE() {
var re = /[a-z]/;
re.foo = bar;
return re;
}
var reg = getRE(),
re2 = getRE();
console.log(reg === re2); // true
reg.foo = baz;
console.log(re2.foo); // baz

ES
5, . ,
.

79

: RegExp()
new ( , )
, new.

-
Java

Script
: , , , null undefined. null unde
fined, . -
Number(), String() Boolean().
,
:
//
var n = 100;
console.log(typeof n);

// number

// Number
var nobj = new Number(100);
console.log(typeof nobj); // object

- , , - , toFixed() to
Exponential(). - substring(), charAt()
toLowerCase() ( ) length.
, . .
// ,
var s = hello;
console.log(s.toUpperCase()); // HELLO
//
monkey.slice(3, 6);
// key
//
(22 / 7).toPrecision(3);
// 3.14

,
. ,
new String(hi);, hi:
// :
var s = new String(my string);

80

3.
var n = new Number(101);
var b = new Boolean(true);
// :
var s = my string;
var n = 101;
var b = true;

- ,
.
, .
//
var greet = Hello there;
// ,
// split()
greet.split( )[0]; // Hello
//
greet.smile = true;
//
typeof greet.smile; // undefined

greet , /. , greet
new String(),
smile . ,
. , , , -.
- new :
typeof
typeof
typeof
typeof
typeof

Number(1);
Number(1);
Number(new Number());
String(1);
Boolean(1);

//
//
//
//
//

number
number
number
string
boolean

Error
JavaScript
, Error(), SyntaxError(), TypeError() ,
throw. , , :

81

name
name -, .
Error
, , , RangeError.
message
, .
, ,
, , ,
- .
, throw , - Error. , .
name, message , catch.

.
try {
// - ,
throw {
name: MyErrorType,
//
message: oops,
extra: This was rather embarrassing,
remedy: genericErrorHandler //
//
};
} catch (e) {
//
alert(e.message);
// oops
//
e.remedy();

// genericErrorHandler()

( new), ,
( new), .



, -. :

82

3.


-, ,
.
- (
) .
, ,
new.
, , .
JSON ,
.
.
, :
String(), Number(), Boolean() Error().
, , Date(), . .

( )


()

var o = new Object();

var o = {};

var a = new Array();

var a = [];

var re = new RegExp(


[a-z],
g
);

var re = /[a-z]/g;

var s = new String();

var s = ;

var n = new Number();

var n = 0;

var b = new Boolean();

var b = false;

throw new Error(uh-oh);

throw {
name: Error,
message: uh-oh
};
...
throw Error(uh-oh);

Java
Script, . JavaScript ,
.

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

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

84

4.

.
.
, A, , , B. B
C
, D. . ,
. , JavaScript ,
, .
, , ,
new Function() :
//
//
var add = new Function(a, b, return a + b);
add(1, 2); // 3

, add()
, .
Function() ( eval()), .
, ( ) -
, .
. JavaScript
. ,
. . ,
var , ,
. ,
, , , var
if for while,
if, for
while. , , , . 2, ,
, .

85


, , , , .
:
// -
var add = function add(a, b) {
return a + b;
};

,
-.
( add ) -
, -, -,
. :
// -,
var add = function (a, b) {
return a + b;
};

- ,
- ,
- .
add
-, . ,
name .
name (
ECMA), . add, add.name
add. name
, Firebug,
.
.
, -.
:
function foo() {
//
}

-
- , -

86

4.

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

.

:
-
-? ,
-, . , :
// -,
// callMe
callMe(function () {
// -,
//
});
// -
callMe(function me() {
// -,
// me
});
// -
var myobject = {
say: function () {
// -
}
};

87

- ,
.

.
-, , foo(), bar() local(), -:
//
function foo() {}
function local() {
//
function bar() {}
return bar;
}

name

name. ,
,
. - name . -
(IE) ,
(Firefox, WebKit):
function foo() {}
// -
var bar = function () {};
// -
var baz = function baz() {}; // -
foo.name; // foo
bar.name; //
baz.name; // baz

name Firebug .
,
, name
. name .
, -, .
- -
, - , JavaScript , - .

88

4.


- ,
:
var foo = function bar() {};


(IE),
.


, -
-. , , .
ECMA
Script,
.

, , ,
,
. , , . , -
,
. :
//
//
//
function foo() {
alert(global foo);
}
function bar() {
alert(global bar);
}
function hoistMe() {
console.log(typeof foo); // function
console.log(typeof bar); // undefined
foo(); // local foo
bar(); // TypeError: bar is not a function

89

// -:
// foo
function foo() {
alert(local foo);
}
// -:
// bar,
//
var bar = function () {
alert(local bar);
};
}
hoistMe();

, , , foo bar hoistMe()


foo bar. ,
foo . bar()
. , bar(),
(
bar() ).
, , JavaScript,
. JavaScript:


, . , , introduceBugs() writeCode(), , -
writeCode() ( ) intro
duceBugs(). introduceBugs()
:
function writeCode(callback) {
// ...
callback();
// ...
}

90

4.
function introduceBugs() {
// ...
}
writeCode(introduceBugs);

, introduceBugs()
writeCode() .
,

writeCode() ( ) .


, . ,
,
. , findNodes(). DOM ,
:
var findNodes = function () {
var i = 100000, // ,
nodes = [], //
found;
//
while (i) {
i -= 1;
// ...
nodes.push(found);
}
return nodes;
};

, DOM,
. ,
hide(), , , :
var hide = function (nodes) {
var i = 0, max = nodes.length;
for (; i < max; i += 1) {
nodes[i].style.display = none;
}
};

91

//
hide(findNodes());

,
hide() ,
findNodes(). ,

findNodes().
findNodes(), - .

:
// findNodes(),
//
var findNodes = function (callback) {
var i = 100000,
nodes = [],
found;
// , callback
if (typeof callback !== function) {
callback = false;
}
while (i) {
i -= 1;
// ...
// callback:
if (callback) {
callback(found);
}
nodes.push(found);
}
return nodes;
};

. , findNodes(), callback . callback findNodes() , , ,


,
.

92

4.

hide() ,
:
//
var hide = function (node) {
node.style.display = none;
};
//
findNodes(hide);

,
, ,
. , , findNodes():
//
findNodes(function (node) {
node.style.display = block;
});


,
:
callback(parameters);

,
, .
this , .
,
paint() myapp:
var myapp = {};
myapp.color = green;
myapp.paint = function (node) {
node.style.color = this.color;
};

findNodes():
var findNodes = function (callback) {
// ...
if (typeof callback === function) {
callback(found);
}
// ...
};

93

findNodes(myapp.paint), , , this.color
. this
, findNodes() . find
Nodes() dom (: dom.findNodes()),
this
dom, myapp.
,
, :
findNodes(myapp.paint, myapp);

, findNodes() :
var findNodes = function (callback, callback_obj) {
//...
if (typeof callback === function) {
callback.call(callback_obj, found);
}
// ...
};

call() apply()
.
,
, ,
, . , :
findNodes(myapp.paint, myapp);

:
findNodes(paint, myapp);

findNodes() , :
var findNodes = function (callback, callback_obj) {
if (typeof callback === string) {
callback = callback_obj[callback];
}
//...
if (typeof callback === function) {
callback.call(callback_obj, found);
}
// ...
};

94

4.


; ,

, .
console.log()
click :
document.addEventListener(click, console.log, false);

. , load. ,
, click, keypress,
mouseover, mousemove . JavaScript , ,
, , .
: , , ,
.
, . JavaScript
.
, . , , .
, !,
.


window :
setTimeout() setInterval(). :
var thePlotThickens = function () {
console.log(500ms later...);
};
setTimeout(thePlotThickens, 500);

, thePlotThickens
, , ,

95

setTimeout() . thePlot
Thickens()
, eval().


,
.
, , , ,

. , ,
.

,
, .


,
. - .
,

.
. , ,
. ,
:
var setup = function () {
alert(1);
return function () {
alert(2);
};
};
// setup
var my = setup(); // 1
my();
// 2

setup() , , -

96

4.

, .
, :
var setup = function () {
var count = 0;
return function () {
return (count += 1);
};
};
//
var next = setup();
next(); // 1
next(); // 2
next(); // 3


. , , .
.
.
.
, ,
:
var scareMe = function () {
alert(Boo!);
scareMe = function () {
alert(Double boo!);
};
};
//
scareMe(); // Boo!
scareMe(); // Double boo!

,
, .
, ,
.
, .
, ,
.

97

: ,
, , , .

, ,
, .
, , ,
, .
, scareMe()
:
1. .
2. .
3. .
:
// 1.
scareMe.property = properly;
// 2.
var prank = scareMe;
// 3.
var spooky = {
boo: scareMe
};
//
prank();
prank();
console.log(prank.property);

// Boo!
// Boo!
// properly

//
spooky.boo();
// Boo!
spooky.boo();
// Boo!
console.log(spooky.boo.property); // properly
//
scareMe();
scareMe();
console.log(scareMe.property);

// Double boo!
// Double boo!
// undefined

, , , , .
prank() Boo!.

98

4.

scareMe() ,
prank , property. ,
boo() spooky.

scareMe(), ,
Double boo. ,
scareMe.property.


,
, .
:
(function () {
alert(watch out!);
}());

- (
, ) .
ECMAScript, .
:
-. (
-.)
, .
,
( , ).
(
),
JSLint :
(function () {
alert(watch out!);
})();

,
. :
,
, .
,

99

. ,
, ,
.
,
:
(function () {
var days = [Sun, Mon, Tue, Wed, Thu, Fri, Sat],
today = new Date(),
msg = Today is + days[today.getDay()] + , + today.getDate();
alert(msg);
}()); // Today is Fri, 13


, days, today msg
.


, :
// :
// I met Joe Black on Fri Aug 13 2010 23:26:59 GMT-0800 (PST)
(function (who, when) {
console.log(I met + who + on + when);
}(Joe Black, new Date()));

,
window; , :
(function (global) {
// `global`
}(this));

, -

100

4.

, ,
, , .

, ,
:
var result = (function () {
return 2 + 2;
}());

, , , , , , .
, :
var result = function () {
return 2 + 2;
}();

, . () , , result . result , , 4.
, :
var result = (function () {
return 2 + 2;
})();

.
,
. , .

, getResult res,
:
var getResult = (function () {
var res = 2 + 2;
return function () {

101

return res;
};
}());


. , ,
, ,
, .
, :
var o = {
message: (function () {
var who = me,
what = call;
return what + + who;
}()),
getMsg: function () {
return this.message;
}
};
// usage
o.getMsg(); // call me
o.message; // call me

o.message , , , , ,
, .


.
,
. ,
, , .
, , .

(
, bookmarklets),
(
).

102

4.


. , , JavaScript. ,
, .
( )
, - .
, ,
,
.
( module1)
:
// module1 module1.js
(function () {
// module1...
}());

, . ,
,
,
, .


,
, ,
,
.
, init(), . init() .
:
({
//
//
maxwidth: 600,
maxheight: 400,
//
gimmeMax: function () {

103

return this.maxwidth + x + this.maxheight;


},
//
init: function () {
console.log(this.gimmeMax());
// ...
}
}).init();


. ( ), JavaScript , ,
, . (
if for.) init().
, init(). ,
:
({...}).init();
({...}.init());

, : .
, , ,
( ), . , , ,
, ,
, .
, JavaScript , , . ,
.
Google Closure Compiler ,

,
:
({d:600,c:400,a:function(){return this.d+x+this.c},b:function(){console.
log(this.a())}}).b();

104

4.

init(). , ,
init().

, (
), . ,
, ,
.
( ).
, , XMLHttpRequest , ,
, ,
ActiveX. , (
) ,
XHR.
DOM
, .
,
:
//
var utils = {
addListener: function (el, type, fn) {
if (typeof window.addEventListener === function) {
el.addEventListener(type, fn, false);
} else if (typeof document.attachEvent === function) { // IE
el.attachEvent(on + type, fn);
} else { //
el[on + type] = fn;
}
},
removeListener: function (el, type, fn) {
// ...

105

}
};

, . , utils.addListener() utils.
removeListener(), .
, , ,
.
, . ,
:
//
//
var utils = {
addListener: null,
removeListener: null
};
//
if (typeof window.addEventListener === function) {
utils.addListener = function (el, type, fn) {
el.addEventListener(type, fn, false);
};
utils.removeListener = function (el, type, fn) {
el.removeEventListener(type, fn, false);
};
} else if (typeof document.attachEvent === function) { // IE
utils.addListener = function (el, type, fn) {
el.attachEvent(on + type, fn);
};
utils.removeListener = function (el, type, fn) {
el.detachEvent(on + type, fn);
};
} else { //
utils.addListener = function (el, type, fn) {
el[on + type] = fn;
};
utils.removeListener = function (el, type, fn) {
el[on + type] = null;
};
}


. ,
. , ,

106

4.

window.addEventListener, , IE, XMLHttpRequest, ,


. ,
.
, .addEventListener .removeEventListener,
.

, ,
.


, .
. , , ,
, length, , :
function func(a, b, c) {}
console.log(func.length); // 3


. , ,
( ) ,

. (memorization).
myFunc cache,
myFunc.cache. cache (),
param, , , .
, :
var myFunc = function (param) {
if (!myFunc.cache[param]) {
var result = {};
// ... ...
myFunc.cache[param] = result;
}
return myFunc.cache[param];
};
//
myFunc.cache = {};

107

,
param (, ).
,
,
. ,
JSON
cache:
var myFunc = function () {
var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)),
result;
if (!myFunc.cache[cachekey]) {
result = {};
// ... ...
myFunc.cache[cachekey] = result;
}
return myFunc.cache[cachekey];
};
//
myFunc.cache = {};

, . , , .
arguments.callee, . , ,
, ECMAScript 5, arguments.callee :
var myFunc = function (param) {
var f = arguments.callee,
result;
if (!f.cache[param]) {
result = {};
// ... ...
f.cache[param] = result;
}
return f.cache[param];
};
//
myFunc.cache = {};

108

4.



,
,
.
,
. , ,
.
, addPerson(),
:
function addPerson(first, last) {...}

, .

( ):
function addPerson(first, last, dob, gender, address) {...}


. ,
, . , :
addPerson(Bruce, Wayne, new Date(), null, null, batman);

.
. conf:
addPerson(conf);

, :
var conf = {
username: batman,
first: Bruce,
last: Wayne
};
addPerson(conf);

109

, ,

:


, , , DOM CSS ,

.

,
(currying) . , , , .



, , . Java
Script Function.prototype.apply(),
JavaScript , .
:
//
var sayHi = function (who) {
return Hello + (who ? , + who : ) + !;
};
//
sayHi();
sayHi(world);

// Hello!
// Hello, world!

//
sayHi.apply(null, [hello]); // Hello, hello!

,
. apply() : ,
this, , arguments, , . null, this -

110

4.

, ,
.
, apply() , null ( ). apply() :
var alien = {
sayHi: function (who) {
return Hello + (who ? , + who : ) + !;
}
};
alien.sayHi(world);
// Hello, world!
alien.sayHi.apply(alien, [humans]); // Hello, humans!

sayHi() this
alien. .
, , , 1, .
, apply() Function.prototype
call(), , apply(). , : ,
:
// ,
alien.sayHi.apply(alien, [humans]); // Hello, humans!
alien.sayHi.call(alien, humans);
// Hello, humans!


, , , :
, ? ,
, .
, add(), : x y. ,
, x 5, y 4:

(syntactic sugar) , , , . . .

111

//
// JavaScript
//
function add(x, y) {
return x + y;
}
//
add(5, 4);
// 1
function add(5, y) {
return 5 + y;
}
// 2
function add(5, 4) {
return 5 + 4;
}

1 2 JavaScript, , . x 5.
.
1 : . , (),
.

partialApply():
var add = function (x, y) {
return x + y;
};
//
add.apply(null, [5, 4]); // 9
//
var newadd = add.partialApply(null, [5]);
//
newadd.apply(null, [4]); // 9

,
, . add(5)(4),
add(5) , -

112

4.

(4). add(5, 4) ,
add(5)(4).
: JavaScript
partialApply()
. , Java
Script , .
, ,
,
(currying).

. (Haskell
Curry). ( Haskell .)
,
. (schnfinkelisation),
, (Moses Schnfinkel), .
( ) ?
,
. JavaScript
add() , .
:
// add()
//
function add(x, y) {
var oldx = x, oldy = y;
if (typeof oldy === undefined) { //
return function (newy) {
return oldx + newy;
};
}
//
return x + y;
}
//
typeof add(5); // function
add(3)(4);
// 7

113

//
var add2000 = add(2000);
add2000(10); // 2010

add()
, .
x y oldx
oldy. , oldx, . , add() x y, . add()
, . oldx oldy, x ,
newy y:
// add()
//
function add(x, y) {
if (typeof y === undefined) { // partial
return function (y) {
return x + y;
};
}
//
return x + y;
}

add(). ? , ,
? ,
schonfinkelize(), .
schonfinkelize() , , , ( curry
), , ,
.
, :
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}

114

4.

schonfinkelize() ,
, - , arguments JavaScript . slice(),
Array.prototype, arguments . schonfinkel
ize() , slice()
( slice),
( stored_args), ,
. schonfinkelize() .
, ( ) ,
stored_args, slice. (stored_args)
(new_args) fn
( ).
,
, :
//
function add(x, y) {
return x + y;
}
//
var newadd = schonfinkelize(add, 5);
newadd(4);
// 9
//
schonfinkelize(add, 6)(7);
// 13

schonfinkelize() .
:
//
function add(a, b, c, d, e) {
return a + b + c + d + e;
}
//
schonfinkelize(add, 1, 2, 3)(5, 5);
// 16
//
var addOne = schonfinkelize(add, 1);
addOne(10, 10, 10, 10);
// 41
var addSix = schonfinkelize(addOne, 2, 3);
addSix(5, 5);
// 16

115


, , ,
. , . (
) , .



JavaScript . .
JavaScript, :
1. , .
2. , .
, ,
.
JavaScript
:
1. -.
2. - ( , ,
), .
3. -, .

, :
1. API,
. :

.


.

116

4.


.
2. , ( - ) .
:

.


, , .
,
,
, ,
.
3. , . :

, .

, , ,
, .


JavaScript

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

.
, , -,

.


, ,
.
JavaScript ,
.
, , -

118

5.

( ) , .
.
:
// : 5
// :
//
function Parent() {}
function Child() {}
//
var some_var = 1;
//
var module1 = {};
module1.data = {a: 1, b: 2};
var module2 = {};

, , MYAPP, :
// : 1
//
var MYAPP = {};
//
MYAPP.Parent = function () {};
MYAPP.Child = function () {};
//
MYAPP.some_var = 1;
// -
MYAPP.modules = {};
//
MYAPP.modules.module1 = {};
MYAPP.modules.module1.data = {a: 1, b: 2};
MYAPP.modules.module2 = {};


, , ,
. , ,
, -

119

. ( ,
.)


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

, .
,
.





. , . ,
, , , . ,
, ,
, :
//
var MYAPP = {};
//
if (typeof MYAPP === undefined) {
var MYAPP = {};
}
//
var MYAPP = MYAPP || {};

, . , MYAPP.modules.module2, -

120

5.

,
. ,
, . namespace() ,
, :
//
MYAPP.namespace(MYAPP.modules.module2);
// :
// var MYAPP = {
//
modules: {
//
module2: {}
//
}
// };

, , , :
var MYAPP = MYAPP || {};
MYAPP.namespace = function (ns_string) {
var parts = ns_string.split(.),
parent = MYAPP,
i;
//
if (parts[0] === MYAPP) {
parts = parts.slice(1);
}
for (i = 0; i < parts.length; i += 1) {
// ,
if (typeof parent[parts[i]] === undefined) {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};

:
//
var module2 = MYAPP.namespace(MYAPP.modules.module2);
module2 === MYAPP.modules.module2; // true
// `MYAPP`
MYAPP.namespace(modules.module51);

121

//
MYAPP.namespace(once.upon.a.time.there.was.this.long.nested.property);

. 5.1 , ,
, Firebug.

.5.1. MYAPP Firebug


JavaScript , . , YUI2
YAHOO, , , , YAHOO.util.Dom ( DOM) YAHOO.util.Event
( Events).
, ,
.
, :
var myFunction = function () {
//
var event = YAHOO.util.Event,
dom = YAHOO.util.Dom;
//
// event dom...
};

, :

122

5.

, .
.
( dom) , ( YAHOO),
,
( YAHOO.util.Dom),
.

. ,
.
JavaScript, YUICompressor
Google Closure Compiler,
( event
, A), ,
, .
. test2(), , ,
- ,
, ,
:
function test1() {
alert(MYAPP.modules.m1);
alert(MYAPP.modules.m2);
alert(MYAPP.modules.m51);
}
/*
test1:
alert(MYAPP.modules.m1);alert(MYAPP.modules.m2);alert(MYAPP.modules.m51)
*/
function test2() {
var modules = MYAPP.modules;
alert(modules.m1);
alert(modules.m2);
alert(modules.m51);
}
/*
test2:
var a=MYAPP.modules;alert(a.m1);alert(a.m2);alert(a.m51)
*/

123


JavaScript
(private), (protected) (public)
, Java .
:
var myobj = {
myprop: 1,
getProp: function () {
return this.myprop;
}
};
console.log(myobj.myprop);
// `myprop`
console.log(myobj.getProp()); // getProp() -

-
:
function Gadget() {
this.name = iPod;
this.stretch = function () {
return iPad;
};
}
var toy = new Gadget();
console.log(toy.name);
// `name` -
console.log(toy.stretch()); // stretch() -


, - , .
- , , , .
,
. ,
:
function Gadget() {
//
var name = iPod;
//
this.getName = function () {
return name;
};
}
var toy = new Gadget();

124

5.
// `name` ,
console.log(toy.name);
// undefined
// `name`
console.log(toy.getName()); // iPod

, JavaScript . ,
, , , ,
, , .


, ( ).
getName() ,
name.


,
:
Firefox eval()
, ,
.
__parent__ Mozilla Rhino . .

,
, .
. Gadget :
function Gadget() {
//
var specs = {
screen_width: 320,
screen_height: 480,
color: white
};
//
this.getSpecs = function () {

125

return specs;
};
}

, getSpecs()
specs. Gadget
, ,
specs:
var toy = new Gadget(),
specs = toy.getSpecs();
specs.color = black;
specs.price = free;
console.dir(toy.getSpecs());

Firebug .5.2.

.5.2.

,
, .
, getSpecs()
, ,
.
(Principle of Least Authority, POLA), , , . , Gadget ,
,
. ,
, getDimensions(), , .
getSpecs() .
, , , specs . :
extend(), ( ), extend
Deep(), ,
.

126

5.


, , .
, ?
?
, , . ,
, . :
var myobj; //
(function () {
//
var name = my, oh my;
//
// `var`
myobj = {
//
getName: function () {
return name;
}
};
}());
myobj.getName(); // my, oh my

, :
var myobj = (function () {
//
var name = my, oh my;
//
return {
getName: function () {
return name;
}
};
}());
myobj.getName(); // my, oh my

, , .


, , .

127

,
. ,
proto
type .
, .
, .
:
. prototype ,
.
, :
function Gadget() {
//
var name = iPod;
//
this.getName = function () {
return name;
};
}
Gadget.prototype = (function () {
//
var browser = Mobile Webkit;
//
return {
getBrowser: function () {
return browser;
}
};
}());
var toy = new Gadget();
console.log(toy.getName());
//
console.log(toy.getBrowser()); //

,
. , ,
, .
,

128

5.

. ,
, . ECMAScript 5
, .
( ,
(Christian Heilmann),
).
, :
var myarray;
(function () {
var astr = [object Array],
toString = Object.prototype.toString;
function isArray(a) {
return toString.call(a) === astr;
}
function indexOf(haystack, needle) {
var i = 0,
max = haystack.length;
for (; i < max; i += 1) {
if (haystack[i] === needle) {
return i;
}
}
return -1;
}
myarray = {
isArray: isArray,
indexOf: indexOf,
inArray: indexOf
};
}());

, isArray()
indexOf(). myarray , . indexOf()
: indexOf ECMAScript5
inArray PHP. myarray:

129


myarray.isArray([1,2]);
myarray.isArray({0: 1});
myarray.indexOf([a, b, z], z);
myarray.inArray([a, b, z], z);

//
//
//
//

true
false
2
2

, , - indexOf(), indexOf() ,
inArray() :
myarray.indexOf = null;
myarray.inArray([a, b, z], z); // 2


. ,
JavaScript
,
,
,
(, ) .
, , :




. namespace(), ,
, :
MYAPP.namespace(MYAPP.utilities.array);

. , , . ,
, :
MYAPP.utilities.array = (function () {
return {
// ...
};
}());

130

5.

:
MYAPP.utilities.array = (function () {
return {
inArray: function (needle, haystack) {
// ...
},
isArray: function (a) {
// ...
}
};
}());

,
, , . , .

, .
, , :
MYAPP.namespace(MYAPP.utilities.array);
MYAPP.utilities.array = (function () {
//
var uobj = MYAPP.utilities.object,
ulang = MYAPP.utilities.lang,
//
array_string = [object Array],
ops = Object.prototype.toString;
//
// ...
// var
//
// ...
//
return {
inArray: function (needle, haystack) {
for (var i = 0, max = haystack.length; i < max; i += 1) {
if (haystack[i] === needle) {
return true;
}
}
},

131

isArray: function (a) {


return ops.call(a) === array_string;
}
// ...
};
}());

,
.


, . ,
, .
, , :
MYAPP.utilities.array = (function () {
//
var array_string = [object Array],
ops = Object.prototype.toString,
//
inArray = function (haystack, needle) {
for (var i = 0, max = haystack.length; i < max; i += 1) {
if (haystack[i] === needle) {
return i;
}
}
return -1;
},
isArray = function (a) {
return ops.call(a) === array_string;
};
// var
//
return {
isArray: isArray,
indexOf: inArray
};
}());

132

5.

,
MYAPP.utilities.array, .
.
, , , , .
,
- MYAPP.utilities.Array:
MYAPP.namespace(MYAPP.utilities.Array);
MYAPP.utilities.Array = (function () {
//
var uobj = MYAPP.utilities.object,
ulang = MYAPP.utilities.lang,
// ...
Constr;
// var
//
// ...
// --
Constr = function (o) {
this.elements = this.toArray(o);
};
// --
Constr.prototype = {
constructor: MYAPP.utilities.Array,
version: 2.0,
toArray: function (obj) {
for (var i = 0, a = [], len = obj.length; i < len; i += 1) {
a[i] = obj[i];
}
return a;
}
};
// ,
//
return Constr;
}());

133

, :
var arr = new MYAPP.utilities.Array(obj);



, .
,
.

,
:
MYAPP.utilities.module = (function (app, global) {
// global
// app
//
}(MYAPP, this));


, , :
,
.


,
, MYAPP.
, MYAPP.utilities.array,
, .
,
,
.
, , YUI 3, , , YUI3.

134

5.


; : Sandbox().

,
.
, :
new Sandbox(function (box) {
// ...
});

box MYAPP ;
,
.
:
(
new 3) , new.
Sandbox() , ,
.
, ,
Sandbox(), .
, .
new , ajax event:
Sandbox([ajax, event], function (box) {
// console.log(box);
});

, :
Sandbox(ajax, dom, function (box) {
// console.log(box);
});

, * . , , *.

, :

135

Sandbox(*, function (box) {


// console.log(box);
});
Sandbox(function (box) {
// console.log(box);
});

,
; , :
Sandbox(dom, event, function (box) {
// dom event
Sandbox(ajax, function (box) {
// box
// box
// box,
//...
// , jax
});
// jax
});

, , , .

, , - Sandbox().
,
, .
, Sandbox() ,
.


,
, .
- Sandbox() , -

136

5.

modules. ,
-, , , :
Sandbox.modules = {};
Sandbox.modules.dom = function (box) {
box.getElement = function () {};
box.getStyle = function () {};
box.foo = bar;
};
Sandbox.modules.event = function (box) {
// Sandbox :
// box.constructor.prototype.m = mmm;
box.attachEvent = function () {};
box.detachEvent = function () {};
};
Sandbox.modules.ajax = function (box) {
box.makeRequest = function () {};
box.getResponse = function () {};
};

dom, event ajax,


-.
, , box
.


Sandbox() (,
,
):
function Sandbox() {
//
var args = Array.prototype.slice.call(arguments),
// -
callback = args.pop(),
//
//
modules = (args[0] && typeof args[0] === string) ? args : args[0],
i;
// ,
//
if (!(this instanceof Sandbox)) {
return new Sandbox(modules, callback);
}

137

// `this`, :
this.a = 1;
this.b = 2;
//
//
//
if

`this`
*

(!modules || modules === *) {
modules = [];
for (i in Sandbox.modules) {
if (Sandbox.modules.hasOwnProperty(i)) {
modules.push(i);
}
}

}
//
for (i = 0; i < modules.length; i += 1) {
Sandbox.modules[modules[i]](this);
}
//
callback(this);
}
// ,
Sandbox.prototype = {
name: My Application,
version: 1.0,
getName: function () {
return this.name;
}
};

:
, this Sandbox,
( Sandbox() new), .
this.
.

,
* (
), ,
. , , ,

138

5.

. , , YUI3.
(
), , , .
, , , .
.
. box, .


,
. ,
, , . , max() MathUtils MathUtils.max(3, 5). ,
.
, , ,
.
,
JavaScript.


JavaScript
. ,
, -
. , ,
, .
, ,
.
Gadget
isShiny() setPrice().
isShiny() ,
- (gadget), - -, , (shiny). setPrice(),
, ,
:

139

//
var Gadget = function () {};
//
Gadget.isShiny = function () {
return you bet;
};
// ,
Gadget.prototype.setPrice = function (price) {
this.price = price;
};

. isShiny() ,
:
//
Gadget.isShiny(); // you bet
//
var iphone = new Gadget();
iphone.setPrice(500);


, iphone:
typeof Gadget.setPrice; // undefined
typeof iphone.isShiny; // undefined


. , , , :
Gadget.prototype.isShiny = Gadget.isShiny;
iphone.isShiny(); // you bet


this .
Gadget.isShiny() this isShiny()
- Gadget. iphone.isShiny() this iphone.
, ,
- .
instanceof:
//
var Gadget = function (price) {

140

5.
this.price = price;
};
//
Gadget.isShiny = function () {
//
var msg = you bet;
if (this instanceof Gadget) {
// ,
msg += , it costs $ + this.price + !;
}
return msg;
};
// ,
Gadget.prototype.isShiny = function () {
return Gadget.isShiny.call(this);
};

:
Gadget.isShiny(); // you bet

:
var a = new Gadget(499.99);
a.isShiny();
// you bet, it costs $499.99!


,
, .
, :
, -

counter
Gadget. , , , .
Gadget, :
var Gadget = (function () {
// /
var counter = 0;

141


//
return function () {
console.log(counter += 1);
};
}()); //

Gadget counter . ,
, counter :
var g1 = new Gadget(); // 1
var g2 = new Gadget(); // 2
var g3 = new Gadget(); // 3

counter, , Gadget. ,
? , ,
getLastId(), :
//
var Gadget = (function () {
// /
var counter = 0,
NewGadget;
//
NewGadget = function () {
counter += 1;
};
//
NewGadget.prototype.getLastId = function () {
return counter;
};
//
return NewGadget;
}()); //

:
var iphone = new Gadget();
iphone.getLastId();
var ipod = new Gadget();

// 1

142

5.
ipod.getLastId();
var ipad = new Gadget();
ipad.getLastId();

// 2
// 3

( , )
. ,

. 7, (singleton),
, ,
.

-
JavaScript ,

const.
,
, . JavaScript:
Math.PI;
// 3.141592653589793
Math.SQRT2;
// 1.4142135623730951
Number.MAX_VALUE; // 1.7976931348623157e+308

, :
//
var Widget = function () {
// ...
};
//
Widget.MAX_HEIGHT = 320;
Widget.MAX_WIDTH = 480;


; ,
.
- ,
, . , , , , .

143

con
stant :
set(name, value)
.
isDefined(name)
name.
get(name)
.
. , ,
, toString hasOwnProperty, hasOwnProperty(),
:
var constant = (function () {
var constants = {},
ownProp = Object.prototype.hasOwnProperty,
allowed = {
string: 1,
number: 1,
boolean: 1
},
prefix = (Math.random() + _).slice(2);
return {
set: function (name, value) {
if (this.isDefined(name)) {
return false;
}
if (!ownProp.call(allowed, typeof value)) {
return false;
}
constants[prefix + name] = value;
return true;
},
isDefined: function (name) {
return ownProp.call(constants, prefix + name);
},
get: function (name) {
if (this.isDefined(name)) {
return constants[prefix + name];
}
return null;
}

144

5.
};
}());

:
// ,
constant.isDefined(maxwidth); // false
//
constant.set(maxwidth, 480); // true
//
constant.isDefined(maxwidth); // true
//
constant.set(maxwidth, 320); // false
// ?
constant.get(maxwidth);

// 480



:
myobj.method1(hello).method2().method3(world).method4();

, -
, this
, . ,
:
var obj = {
value: 1,
increment: function () {
this.value += 1;
return this;
},
add: function (v) {
this.value += v;
return this;
},
shout: function () {
alert(this.value);
}
};

method()

145

//
obj.increment().add(3).shout(); // 5
// ,
obj.increment();
obj.add(3);
obj.shout();
// 5


,

, .
,
, , . .
,
. ,
, .
, , ,
, , .
(Robert Martin), Clean Code1,
, .
, , ,
, , this. , , jQuery. DOM API, , , :
document.getElementsByTagName(head)[0].appendChild(newnode);

method()
JavaScript ,
.
JavaScript ,
. ,
(Douglas Crockford),
method(). , , JavaScript

: , .
. . . , 2010.

146

5.

,
, , .
- Java.
.
, ,
. ,
, prototype .
prototype - , .
,
, .
method() .

method() , :
var Person = function (name) {
this.name = name;
}.
method(getName, function () {
return this.name;
}).
method(setName, function (name) {
this.name = name;
return this;
});

,
method(),
method() . , ,
.
method() :


Person. , , , this ,
Person.

147

Person()
:
var a = new Person(Adam);
a.getName();
// Adam
a.setName(Eve).getName(); // Eve

,
, setName()
this.
, method():
if (typeof Function.prototype.method !== function) {
Function.prototype.method = function (name, implementation) {
this.prototype[name] = implementation;
return this;
};
}

method() , . , , , implementa
tion. this -,
.



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

,
, .
-
, ( ), method().




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

, ,
1: .

. , . , . , . -
. . . , 2001.

149

, Java
Script, ,
. ,
- .
.
,
, .
,
( Java, ) , . JavaScript .
JavaScript -,
.
JavaScript -, new .
Java :
Person adam = new Person();

JavaScript :
var adam = new Person();

, Java
, adam,
Person, . JavaScript , Person
, , Person .
JavaScript
, .
. ,
,
.

, .
,
, .
,
.

150

6.



, ,
- Child(), , Parent().
,
. , , ,
. ,
JavaScript .

Parent() Child():
//
function Parent(name) {
this.name = name || Adam;
}
//
Parent.prototype.say = function () {
return this.name;
};
//
function Child(name) {}
//
inherit(Child, Parent);

,
say(), ,
inherit(), .
inherit() , .
.

1:

, Parent()
prototype Child(). inherit():

1:

151

function inherit(C, P) {
C.prototype = new P();
}

, prototype ,
,
(), ,
. ,
new .
new Child(), Parent() ,
:
var kid = new Child();
kid.say(); // Adam



( , this
, name),
( say()).
,
.
, . new Parent(),
( .6.1 2).
name. say()
(, : (new Parent).say()), , 2 . __proto__,
prototype Parent(),
1 (Parent.prototype),
say(). ,
(1)
Parent.prototype
say()
(2)
new Parent()
name = Adam
__proto__
.6.1. Parent()

152

6.

, ,
, , , . , __proto__, , , (,
Firefox).
, , var kid = new Child() inherit(). .6.2.
(1)
Parent.prototype
say()
(2)
new Parent()
name = Adam
__proto__
(3)
new Child()
__proto__
.6.2.

Child()
Child.prototype. new Child() , ,
__proto__. __proto__ , new Parent()
inherit().
, kid.say()?
3 , , , 2.
, 1, .
say() this.name, . . this 3, name.
2,
name Adam.

153

1:

, . , :
var kid = new Child();
kid.name = Patrick;
kid.say(); // Patrick

, .6.3.
(1)
Parent.prototype
say()
(2)
new Parent()
name = Adam
__proto__
(3)
new Child()
__proto__
name = Patrick
.6.3.

kid.name
name 2,
kid 3. kid.say() say,
, 3, 2 , , 1. this.name (
kid.name) ,
3.
delete kid.name,
name
name 2.

1
,
, , . , -

154

6.


.

.

, inherit() , ,
. :
var s = new Child(Seth);
s.say(); // Adam

, .

, ,
,
.

2:


, this :
function Child(a, c, b, d) {
Parent.apply(this, arguments);
}

,
. , ,
.

, 1, .
:
//
function Article() {
this.tags = [js, css];
}
var article = new Article();
// article
// 1
function BlogPost() {}

2:

155

BlogPost.prototype = article;
var blog = new BlogPost();
// ,
// `new Article()`,
//
// article
//
function StaticPage() {
Article.call(this);
}
var page = new StaticPage();
alert(article.hasOwnProperty(tags)); // true
alert(blog.hasOwnProperty(tags));
// false
alert(page.hasOwnProperty(tags));
// true

Article() . blog
tags ,
, hasOwnProperty() false.
page tags,
tags ( ).
,
tags:
blog.tags.push(html);
page.tags.push(php);
alert(article.tags.join(, )); // js, css, html

tags blog,
,
, blog.tags article.tags, . page.tags article,
page.tags , .


, Parent() Child().
Child() :
//
function Parent(name) {
this.name = name || Adam;
}

156

6.
//
Parent.prototype.say = function () {
return this.name;
};
//
function Child(name) {
Parent.apply(this, arguments);
}
var kid = new Child(Patrick);
kid.name;
// Patrick
typeof kid.say; // undefined

.6.4 new Child


Parent. , Child.prototype , .
kid name,
say(), .
,

; __proto__ .
(1)
Parent.prototype
say()
(2)
new Parent("Adam")
name = Adam
__proto__
(4)
Child.prototype
(3)
new Parent("Patrick")
name = Patrick
__proto__
.6.4.

2:

157


:
function Cat() {
this.legs = 4;
this.say = function () {
return meaowww;
}
}
function Bird() {
this.wings = 2;
this.fly = true;
}
function CatWings() {
Cat.apply(this);
Bird.apply(this);
}
var jane = new CatWings();
console.dir(jane);

.6.5. .

.6.5. CatWings Firebug



, ,
, , ,
.

158

6.

,
, .
, , , kid
say()? .

3:

, prototype :
function Child(a, c, b, d) {
Parent.apply(this, arguments);
}
Child.prototype = new Parent();

, (
).
. , , Java , ,
,
.
, . ( name )
.
,
:
//
function Parent(name) {
this.name = name || Adam;
}
//
Parent.prototype.say = function () {
return this.name;
};
//
function Child(name) {

4:

159

Parent.apply(this, arguments);
}
Child.prototype = new Parent();
var kid = new Child(Patrick);
kid.name;
// Patrick
kid.say();
// Patrick
delete kid.name;
kid.say();
// Adam

, say(). , name ,
, .
.6.6
. . 6.3, .
(1)
Parent.prototype
say()
(2)
new Parent()
name = Adam
__proto__
(3)
new Child("Patrick")
name = Patrick
__proto__
.6.6.

4:

, ,

.

160

6.


, this. ,
, . :
function inherit(C, P) {
C.prototype = P.prototype;
}

, , .
, ,
, - , , ,
.
.6.7, ,
say(). name.
(1)
Parent.prototype
say()
(2)
new Parent()
name = Adam
__proto__

(3)
new Child()
__proto__

.6.7.

5:

,
, , ,
.
,
F(), . prototype F()
. :

161

5:
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
}


( 1), ( .6.8).
(1)
Parent.prototype
say()
(2)
new Parent()
name = Adam
__proto__

(4)
new F()
__proto__

(3)
new Child()
__proto__
.6.8.
() F()

, . , , .
:
var kid = new Child();

kid.name, undefined. name


, new Parent() , . kid.say() 3, . 4 ,
1, , -

162

6.

, Parent(), , .


,
.
.
uber, super , superclass , JavaScript .
:
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
}


, ,
-, .
, , Parent(),
. ,
inherit(), :
// , ,
function Parent() {}
function Child() {}
inherit(Child, Parent);
//
var kid = new Child();
kid.constructor.name;
// Parent
kid.constructor === Parent; // true

constructor ,
. , ,
.

:

163

klass()
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
C.prototype.constructor = C;
}

, , YUI (, , )
, , .

, ,
.


, () ,
. prototype.
:
var inherit = (function () {
var F = function () {};
return function (C, P) {
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
C.prototype.constructor = C;
}
}());

klass()
JavaScript , ( ). , :
, , initialize, _init ,
.
.

164

6.

() .
(
) , .

, JavaScript. -, , :
var Man = klass(null, {
__construct: function (what) {
console.log(Mans constructor);
this.name = what;
},
getName: function () {
return this.name;
}
});


klass(). Klass() Object.prototype,
.
: , ,
. PHP, , __con
struct. Man,
(
Object). Man name,
__construct, getName(). ,
( ):
var first = new Man(Adam); // Mans constructor
first.getName();
// Adam

SuperMan:
var SuperMan = klass(Man, {
__construct: function (what) {
console.log(SuperMans constructor);
},
getName: function () {
var name = SuperMan.uber.getName.call(this);
return I am + name;
}
});

klass()

165

klass() Man. , getName() getName(),


, uber () SuperMan. :
var clark = new SuperMan(Clark Kent);
clark.getName(); // I am Clark Kent

Mans construc
tor, Supermans constructor.
, ?
instanceof :
clark instanceof Man;
// true
clark instanceof SuperMan; // true

, klass():
var klass = function (Parent, props) {
var Child, F, i;
// 1.
//
Child = function () {
if (Child.uber && Child.uber.hasOwnProperty(__construct)) {
Child.uber.__construct.apply(this, arguments);
}
if (Child.prototype.hasOwnProperty(__construct)) {
Child.prototype.__construct.apply(this, arguments);
}
};
// 2.
//
Parent = Parent || Object;
F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.uber = Parent.prototype;
Child.prototype.constructor = Child;
// 3.
//
for (i in props) {
if (props.hasOwnProperty(i)) {
Child.prototype[i] = props[i];

166

6.
}
}
//
return Child;
};

klass() , :
1. - Child().
. __con
struct, . uber
__construct ( , ). uber , , Object,
Man.
2. . , . : Object,
Parent .
3.
( __construct getName ), ,
Child.
? , , , .
,
.
, .
, ,
, -
.



.
.
:
, , , .

167

, :
// ,
var parent = {
name: Papa
};
//
var child = object(parent);
//
alert(child.name); // Papa

parent, , child, ,
parent. child object().
JavaScript ( Object()), .
, - F(), prototype F() :
function object(o) {
function F() {}
F.prototype = o;
return new F();
}

, , . 6.9.
child , , parent __proto__.
(1)
parent
name = Papa
(2)
child = new F()
__proto__
.6.9.

168

6.

(
). -.
,
, :
//
function Person() {
//
this.name = Adam;
}
// ,
Person.prototype.getName = function () {
return this.name;
};
// Person
var papa = new Person();
//
var kid = object(papa);
// ,
// ,
kid.getName(); // Adam

.
, ,
.
:
//
function Person() {
//
this.name = Adam;
}
// ,
Person.prototype.getName = function () {
return this.name;
};
//
var kid = object(Person.prototype);
typeof kid.getName; // function,
typeof kid.name;
// undefined,

169

ECMAScript5
ECMAScript 5
.
Object.create(). , , object(); :
var child = Object.create(parent);

Object.create() .

.
. :
var child = Object.create(parent, {
age: { value: 2 }
// ECMA5
});
child.hasOwnProperty(age); // true

JavaScript. , YUI3
Y.Object():
YUI().use(*, function (Y) {
var child = Y.Object(parent);
});


. . extend(),
:
function extend(parent, child) {
var i;
child = child || {};
for (i in parent) {
if (parent.hasOwnProperty(i)) {
child[i] = parent[i];
}
}
return child;
}

. child , , -

170

6.


:
var dad = {name: Adam};
var kid = extend(dad);
kid.name; // Adam

. , ,
, ,
. ( JavaScript ) , , .
( ), , . :
var dad = {
counts: [1, 2, 3],
reads: {paper: true}
};
var kid = extend(dad);
kid.counts.push(4);
dad.counts.toString(); // 1,2,3,4
dad.reads === kid.reads; // true

extend() ,
. ,
, , . , , . ,
3. , extend(), ,
, :
function extendDeep(parent, child) {
var i,
toStr = Object.prototype.toString,
astr = [object Array];
child = child || {};
for (i in parent) {
if (parent.hasOwnProperty(i)) {
if (typeof parent[i] === object) {
child[i] = (toStr.call(parent[i]) === astr) ? [] : {};
extendDeep(parent[i], child[i]);

171


} else {
child[i] = parent[i];
}
}
}
return child;
}

, , ,
:
var dad = {
counts: [1, 2, 3],
reads: {paper: true}
};
var kid = extendDeep(dad);
kid.counts.push(4);
kid.counts.toString();
dad.counts.toString();

// 1,2,3,4
// 1,2,3

dad.reads === kid.reads; // false


kid.reads.paper = false;
kid.reads.web = true;
dad.reads.paper;

// true

. , Firebug ( Firefox, JavaScript) extend(),


. jQuery extend() . YUI3 Y.clone(),
, , . ( .)
, ; .

, . ,
.

172

6.

; , :
function mix() {
var arg, prop, child = {};
for (arg = 0; arg < arguments.length; arg += 1) {
for (prop in arguments[arg]) {
if (arguments[arg].hasOwnProperty(prop)) {
child[prop] = arguments[arg][prop];
}
}
}
return child;
}

, ,

, . :
var cake = mix(
{eggs: 2, large: true},
{butter: 1, salted: true},
{flour: 3 cups},
{sugar: sure!}
);

.6.10 console.dir(cake), Firebug cake.

.6.10. cake Firebug


, , ,
-,
. .

173


-
. ,

-.
, ,
. , call() apply().
,
extendDeep().
, JavaScript ,
, call()
apply().
, ,
,
. :
// call()
notmyobj.doStuff.call(myobj, param1, p2, p3);
// apply()
notmyobj.doStuff.apply(myobj, [param1, p2, p3]);

myobj notmyobj, doStuff(). myobj


notmyobj, , doStuff().
, ,
. , . ,
( , ).

:
.
, , , arguments.
arguments , slice(),
:

174

6.
function f() {
var args = [].slice.call(arguments, 1, 3);
return args;
}
//
f(1, 2, 3, 4, 5, 6); // [2,3]

, .
, Array Array.proto
type.slice.call(...). ,
, .


, this , call()/apply() , . this,
.
. one, say():
var one = {
name: object,
say: function (greet) {
return greet + , + this.name;
}
};
//
one.say(hi); // hi, object

two, say(), one:


var two = {
name: another object
};
one.say.apply(two, [hello]); // hello, another object

this say() two, this.name


another object. ,
-

175

? ,
:
//
// `this`
var say = one.say;
say(hoho);
// hoho, undefined
//
var yetanother = {
name: Yet another object,
method: function (callback) {
return callback(Hola);
}
};
yetanother.method(one.say); // Hola, undefined

this say() , , . ( ), :
function bind(o, m) {
return function () {
return m.apply(o, [].slice.call(arguments));
};
}

bind() o m,
.
o m .
bind() o
m, .
bind():
var twosay = bind(two, one.say);
twosay(yo); // yo, another object

, , twosay()
, this ,
two, bind(). ,
twosay(), this two.
.

176

6.

Function.prototype.bind()
ECMAScript5 bind()
Function.prototype, , apply() call(), , :
var newFunc = obj.someFunc.bind(myobj, 1, 2, 3);

someFunc() myobj ,
someFunc(). , 4.
, Function.prototype.
bind() , , ES5:
if (typeof Function.prototype.bind === undefined) {
Function.prototype.bind = function (thisArg) {
var fn = this,
slice = Array.prototype.slice,
args = slice.call(arguments, 1);
return function () {
return fn.apply(thisArg, args.concat(slice.call(arguments)));
};
};
}

; ,
bind() ( ), ,
, bind(). :
var twosay2 = one.say.bind(two);
twosay2(Bonjour); // Bonjour, another object

bind()
, say(). :
var twosay3 = one.say.bind(two, Enchant);
twosay3(); // Enchant, another object


JavaScript.
,
. -

177


.
, , , . ,

, , , Java
Script .
. JavaScript
, , ,
.
,
, .


,
, ,
-
. . .

, ,
C++ Java.
JavaScript
, , ,
.
(singleton), ,
JavaScript
.


,
.
, ,
.

JavaScript
?
JavaScript
. ,
, ,

179

.
:
var obj = {
myprop: my value
};

JavaScript ,
, ,
, :
var obj2 = {
myprop: my value
};
obj === obj2; // false
obj == obj2; // false

, ,
, , - .
: (singleton) JavaScript
, 5.

new

JavaScript
, .
JavaScript new,
-,
. ,
new
.
: ,
, ( )
, .

( , (Universe)):

180

7.
var uni = new Universe();
var uni2 = new Universe();
uni === uni2; // true

uni
. ( , ) uni. uni === uni2,
, .
JavaScript?
, Universe
this . :
. ,
, . ,
.
.
. JavaScript ,
. , Universe.instance, .
, instance
,
.
. -
.
.


Universe:
function Universe() {
// , ?
if (typeof Universe.instance === object) {
return Universe.instance;
}
//
this.start_time = 0;
this.bang = Big;

181

//
Universe.instance = this;
// :
// return this;
}
//
var uni = new Universe();
var uni2 = new Universe();
uni === uni2; // true

, , instance . , -
( , ,
),
.



.
, 5. , :
function Universe() {
//
var instance = this;
//
this.start_time = 0;
this.bang = Big;
//
Universe = function () {
return instance;
};
}
//
var uni = new Universe();
var uni2 = new Universe();
uni === uni2; // true

, this . , . -

182

7.

instance
.
, 4. , ,
, ( Universe()) ,
. ,
Universe(), , .
, :
//
Universe.prototype.nothing = true;
var uni = new Universe();
//
//
Universe.prototype.everything = true;
var uni2 = new Universe();

:
//
//
uni.nothing;
uni2.nothing;
uni.everything;
uni2.everything;

//
//
//
//

true
true
undefined
undefined

// :
uni.constructor.name;
// Universe
// :
uni.constructor === Universe; // false

, uni.constructor
Universe(), , -
, .
, :
function Universe() {
//
var instance;

183


//
Universe = function Universe() {
return instance;
};
//
Universe.prototype = this;
//
instance = new Universe();
//
instance.constructor = Universe;
//
instance.start_time = 0;
instance.bang = Big;
return instance;
}

:
//
Universe.prototype.nothing = true;
// true
var uni = new Universe();
Universe.prototype.everything = true; // true
var uni2 = new Universe();
//
uni === uni2;

// true

//
// ,
uni.nothing && uni.everything && uni2.nothing && uni2.everything; // true
//
uni.bang;
// Big
//
uni.constructor === Universe;
// true

.

instance. .
, ,
:
var Universe;
(function () {

184

7.
var instance;
Universe = function Universe() {
if (instance) {
return instance;
}
instance = this;
//
this.start_time = 0;
this.bang = Big;
};
}());

, .

:
,


()
,
, ( ). JavaScript
.
, ( ), ; , . ,
.
, :
CarMaker.
CarMaker factory(), -.
CarMaker.Compact, CarMaker.SUV
CarMaker.Convertible, CarMaker.
,
, , , , .

185

, :
var corolla = CarMaker.factory(Compact);
var solstice = CarMaker.factory(Convertible);
var cherokee = CarMaker.factory(SUV);
corolla.drive(); // Vroom, I have 4 doors
solstice.drive(); // Vroom, I have 2 doors
cherokee.drive(); // Vroom, I have 24 doors

:
var corolla = CarMaker.factory(Compact);

, , .
,
. , new, ,
, , .
, :
//
function CarMaker() {}
//
CarMaker.prototype.drive = function () {
return Vroom, I have + this.doors + doors;
};
//
CarMaker.factory = function (type) {
var constr = type,
newcar;
// ,
//
if (typeof CarMaker[constr] !== function) {
throw {
name: Error,
message: constr + doesnt exist
};
}
//
//
//
if
}

,
,

(typeof CarMaker[constr].prototype.drive !== function) {
CarMaker[constr].prototype = new CarMaker();

186

7.
//
newcar = new CarMaker[constr]();
// -
// ...
return newcar;
};
//
CarMaker.Compact = function () {
this.doors = 4;
};
CarMaker.Convertible = function () {
this.doors = 2;
};
CarMaker.SUV = function () {
this.doors = 24;
};

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


Object(). , , .
, ,
Number(). . ,
, .

. , Object() new, :
var o
n
s
b

=
=
=
=

new Object(),
new Object(1),
Object(1),
Object(true);

//
o.constructor === Object; // true
n.constructor === Number; // true

187


s.constructor === String; // true
b.constructor === Boolean; // true

, Object() , . ,
.

, ,
.
,
.
, , .
, ,
next(). next() , , .
, agg, next() ,
:
var element;
while (element = agg.next()) {
// ...
console.log(element);
}

, , hasNext(), , .
, hasNext(), ,
:
while (agg.hasNext()) {
// ...
console.log(agg.next());
}

, ,
.

() .
, ,
, -

188

7.


:
var agg = (function () {
var index = 0,
data = [1, 2, 3, 4, 5],
length = data.length;
return {
next: function () {
var element;
if (!this.hasNext()) {
return null;
}
element = data[index];
index = index + 2;
return element;
},
hasNext: function () {
return index < length;
}
};
}());

, :
rewind()
.
current()
, next(), .
:
var agg = (function () {
// [...]
return {
// [...]
rewind: function () {
index = 0;
},

189


current: function () {
return data[index];
}
};
}());

:
// 1, 3 5
while (agg.hasNext()) {
console.log(agg.next());
}
//
agg.rewind();
console.log(agg.current()); // 1

: 1, 3, 5 ( ) 1 (
rewind()).

. . JavaScript
, .

.
, ,
, , , .


. , - -. sale. sale , sale.getPrice().
.
, , .
. ,
, -

190

7.

.
. ,
:
var sale = new Sale(100);
sale = sale.decorate(fedtax);
sale = sale.decorate(quebec);
sale = sale.decorate(money);
sale.getPrice();

//
//
//
//
//

100



$112.88

, , :
var sale = new Sale(100);
sale = sale.decorate(fedtax);
sale = sale.decorate(cdn);
sale.getPrice();

//
//
//
//

100

CDN
CDN$ 105.00

, . , .

, ,
. , . uber ( ) , ,
.
sale.
getPrice() money (. 7.1).
, getPrice() money
getPrice() quebec, getPrice()
fedtax . , getPrice(), Sale().
:
function Sale(price) {
this.price = price || 100;
}
Sale.prototype.getPrice = function () {
return this.price;
};

191

Sale.prototype.getPrice()

fedtax.getPrice()

quebec.getPrice()

money.getPrice()

sale.getPrice()

.7.1.

- :
Sale.decorators = {};

.
, getPrice(). , , , :
Sale.decorators.fedtax = {
getPrice: function () {
var price = this.uber.getPrice();
price += price * 5 / 100;
return price;
}
};

. Sale(). :
Sale.decorators.quebec = {
getPrice: function () {
var price = this.uber.getPrice();
price += price * 7.5 / 100;

192

7.
return price;
}
};
Sale.decorators.money = {
getPrice: function () {
return $ + this.uber.getPrice().toFixed(2);
}
};
Sale.decorators.cdn = {
getPrice: function () {
return CDN$ + this.uber.getPrice().toFixed(2);
}
};

, , decorate(), . ,
, :
sale = sale.decorate(fedtax);

fedtax ,
Sale.decorators.fedtax. newobj, , , ( , ,
),
this.
, . , uber
newobj, .
newobj.
newobj .
sale:
Sale.prototype.decorate = function (decorator) {
var F = function () {},
overrides = this.constructor.decorators[decorator],
i, newobj;
F.prototype = this;
newobj = new F();
newobj.uber = F.prototype;
for (i in overrides) {
if (overrides.hasOwnProperty(i)) {
newobj[i] = overrides[i];
}
}
return newobj;
};

193


,
Java

Script
. ,

.
,
, , .
,
, decorate().
decorate() :
var sale = new Sale(100);
sale.decorate(fedtax);
sale.decorate(quebec);
sale.decorate(money);
sale.getPrice();

//
//
//
//
//

100



$112.88

Sale():
function Sale(price) {
this.price = (price > 0) || 100;
this.decorators_list = [];
}

- Sale
.
decora
tors. , getPrice() ,
getPrice(),
; :
Sale.decorators = {};
Sale.decorators.fedtax = {
getPrice: function (price) {
return price + price * 5 / 100;
}
};
Sale.decorators.quebec = {
getPrice: function (price) {
return price + price * 7.5 / 100;
}
};

194

7.
Sale.decorators.money = {
getPrice: function (price) {
return $ + price.toFixed(2);
}
};

decorate() get
Price(). decorate()
, getPrice() . : decorate() , getPrice() .
getPrice(), :
Sale.prototype.decorate = function (decorator) {
this.decorators_list.push(decorator);
};
Sale.prototype.getPrice = function () {
var price = this.price,
i,
max = this.decorators_list.length,
name;
for (i = 0; i < max; i += 1) {
name = this.decorators_list[i];
price = Sale.decorators[name].getPrice(price);
}
return price;
};

,
.
. ,
. get
Price() ,
. , , ,
. , . decorators_list , , -.


.
-

195

, .

. , , validate().
, , .
, , , ,
.
.


, , , :
var data = {
first_name: Super,
last_name: Man,
age: unknown,
username: o_O
};

, , , .
, last_name ,
first_name ,
, age , username
. :
validator.config = {
first_name: isNonEmpty,
age: isNumber,
username: isAlphaNum
};

, , , validate() :
validator.validate(data);
if (validator.hasErrors()) {
console.log(validator.messages.join(\n));
}

196

7.

:
Invalid value for *age*, the value can only be a valid number, e.g. 1, 3.14
or 2010
Invalid value for *username*, the value can only contain characters and
numbers, no special symbols
( *
age
*,
, 1, 3.14 2010.
*username*,
, )

, , .

validate()
:
//
validator.types.isNonEmpty = {
validate: function (value) {
return value !== ;
},
instructions: the value cannot be empty
};
// ,
validator.types.isNumber = {
validate: function (value) {
return !isNaN(value);
},
instructions: the value can only be a valid number, e.g. 1, 3.14 or 2010
};
// ,
validator.types.isAlphaNum = {
validate: function (value) {
return !/[^a-z0-9]/i.test(value);
},
instructions: the value can only contain characters and numbers,
no special symbols
};

, validator, :
var validator = {
//
types: {},
//
//
messages: [],

197


//
// :
config: {},
//
// `data` =>
validate: function (data) {
var i, msg, type, checker, result_ok;
//
this.messages = [];
for (i in data) {
if (data.hasOwnProperty(i)) {
type = this.config[i];
checker = this.types[type];
if (!type) {
continue; //
}
if (!checker) { // --
throw {
name: ValidationError,
message: No handler to validate type + type
};
}
result_ok = checker.validate(data[i]);
if (!result_ok) {
msg = Invalid value for * + i + *, +
checker.instructions;
this.messages.push(msg);
}
}
}
return this.hasErrors();
},
//
hasErrors: function () {
return this.messages.length !== 0;
}
};

, validator
,
. , -

198

7.

. , .
validator vali
date().

(faade) ; .

. , , . ,
.
, .
, :
stopPropagation()
, DOM.
preventDefault()
,
(, ).
, ,
, . ,
, ,
:
var myevent = {
// ...
stop: function (e) {
e.preventDefault();
e.stopPropagation();
}
// ...
};


. , IE:

199

var myevent = {
// ...
stop: function (e) {
//
if (typeof e.preventDefault === function) {
e.preventDefault();
}
if (typeof e.stopPropagation === function) {
e.stopPropagation();
}
// IE
if (typeof e.returnValue === boolean) {
e.returnValue = false;
}
if (typeof e.cancelBubble === boolean) {
e.cancelBubble = true;
}
}
// ...
};


. , (, ). , .
, . ,
,
, , .

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

, . ,

200

7.


, , ,
.
-, .
- , , , .
. 7.2 , , - ,
,
, , .
- .

ok

.7.2.
-

- , . -
-

201

, HTTP-
. ,
-.


, (. 7.3).
http://www.
jspatterns.com/book/7/proxy.html.

.7.3.

202

7.

. , ,
.
URL
, -.
- ; , HTTP-
.
(
) ,
- .

-
:
videos
/
( videos.getInfo())
( videos.getPlayer()).
http
http.make
Request().
- videos.getInfo() http.makeRequest() . -
proxy, videos http makeRequest(), .
-,
-, .

HTML
HTML :
<p><span id=toggle-all>Toggle Checked</span></p>
<ol id=vids>
<li><input type=checkbox checked><a
href=http://new.music.yahoo.com/videos/--2158073>
Gravedigger</a></li>
<li><input type=checkbox checked><a
href=http://new.music.yahoo.com/videos/--4472739>Save Me</a></li>

203

<li><input type=checkbox checked><a


href=http://new.music.yahoo.com/videos/--45286339>Crush</a></li>
<li><input type=checkbox checked><a
href=http://new.music.yahoo.com/videos/--2144530>
Dont Drink The Water</a></li>
<li><input type=checkbox checked><a
href=http://new.music.yahoo.com/videos/--217241800>
Funny the Way It Is </a></li>
<li><input type=checkbox checked><a
href=http://new.music.yahoo.com/videos/--2144532>
What Would You Say</a></li>
</ol>


. C $ ( ):
var $ = function (id) {
return document.getElementById(id);
};

(
8), id=vids :
$(vids).onclick = function (e) {
var src, id;
e = e || window.event;
src = e.target || e.srcElement;
if (src.nodeName !== A) {
return;
}
if (typeof e.preventDefault === function) {
e.preventDefault();
}
e.returnValue = false;
id = src.href.split(--)[1];
if (src.className === play) {
src.parentNode.innerHTML = videos.getPlayer(id);
return;
}
src.parentNode.id = v + id;
videos.getInfo(id);
};

204

7.

- , / ( getInfo())
(
CSS play). ,

getPlayer().
URL href.

id=toggle-all / .
getInfo(), :
$(toggle-all).onclick = function (e) {
var hrefs,
i,
max,
id;
hrefs = $(vids).getElementsByTagName(a);
for (i = 0, max = hrefs.length; i < max; i += 1) {
// play
if (hrefs[i].className === play) {
continue;
}
//
if (!hrefs[i].parentNode.firstChild.checked) {
continue;
}
id = hrefs[i].href.split(--)[1];
hrefs[i].parentNode.id = v + id;
videos.getInfo(id);
}
};

videos
videos :
getPlayer()
HTML, Flash ( ).
updateList()
. ,
-, HTML .
.

205

getInfo()
http, up
dateList() .
:
var videos = {
getPlayer: function (id) {...},
updateList: function (data) {...},
getInfo: function (id) {
var info = $(info + id);
if (!info) {
http.makeRequest([id], videos.updateList);
return;
}
if (info.style.display === none) {
info.style.display = ;
} else {
info.style.display = none;
}
}
};

http
http , JSONP - YQL Yahoo!:
var http = {
makeRequest: function (ids, callback) {
var url = http://query.yahooapis.com/v1/public/yql?q=,
sql = select * from music.video.id where ids IN (%ID%),
format = format=json,
handler = callback= + callback,
script = document.createElement(script);
sql = sql.replace(%ID%, ids.join(,));
sql = encodeURIComponent(sql);
url += sql + & + format + & + handler;
script.src = url;
document.body.appendChild(script);
}
};

206

7.

YQL (Yahoo! Query Language Yahoo!)


-,
SQL- -

-.

, - YQL, , :
select * from music.video.id where ids IN (2158073)

-
, ,
, .
proxy http videos.
, 50 . videos - , -.
- 50 . videos , . 50
, Toggle Checked, . , ,
.
YQL
:
select * from music.video.id where ids IN (2158073, 123456)

videos.getInfo() proxy.makeRequest(), http.make


Request(), :
proxy.makeRequest(id, videos.updateList, videos);

-
, 50 ,
, http , videos.updateList() .

207

- :
var proxy = {
ids: [],
delay: 50,
timeout: null,
callback: null,
context: null,
makeRequest: function (id, callback, context) {
//
this.ids.push(id);
this.callback = callback;
this.context = context;
//
if (!this.timeout) {
this.timeout = setTimeout(function () {
proxy.flush();
}, this.delay);
}
},
flush: function () {
http.makeRequest(this.ids, proxy.handler);
//
this.timeout = null;
this.ids = [];
},
handler: function (data) {
var i, max;
//
if (parseInt(data.query.count, 10) === 1) {
proxy.callback.call(proxy.context, data.query.results.Video);
return;
}
//
for (i = 0, max = data.query.results.Video.length; i < max; i += 1)
{
proxy.callback.call(proxy.context, data.query.results.Video[i]);
}
}
};

208

7.

- -
.
. 7.4 7.5 , ( -)
-.
1
1

Videos

2
2

HTTP

3
3
.7.4.
1
2
3

Videos
1
2
3

1,2,3
1,2,3

HTTP

.7.5. -

209

-
(videos) ,
. . -
http, cache (. 7.6).
, videos
, -
, .

Videos

1
2
1
2

2
2

1,2

HTTP

.7.6. -

.
,
,
.

210

7.

. .
(
), .
, ,
. ,
,
.
(mediator) ,
(. 7.7).
()
-. - , , ,
.

.7.7.


.
, ,

. 1,
0 ( ).
.

211

:
1
2


. (),
, , , (.7.8). (
) . , .
. ,
,
, , .

http://jspatterns.com/book/7/mediator.html.

0:0

.7.8.

, , Player() points name.


play() :
function Player(name) {
this.points = 0;

212

7.
this.name = name;
}
Player.prototype.play = function () {
this.points += 1;
mediator.played();
};

, , update(), -
.
, :
var scoreboard = {
// HTML,
element: document.getElementById(results),
//
update: function (score) {
var i, msg = ;
for (i in score) {
if (score.hasOwnProperty(i)) {
msg += <p><strong> + i + <\/strong>: ;
msg += score[i];
msg += <\/p>;
}
}
this.element.innerHTML = msg;
}
};

- mediator. , , , setup(), players.


played() , ,
. score
scoreboard . keypress()
, ,
, :
var mediator = {
//
players: {},
//
setup: function () {
var players = this.players;
players.home = new Player(Home);

213


players.guest = new Player(Guest);
},
// , -
played: function () {
var players = this.players,
score = {
Home: players.home.points,
Guest: players.guest.points
};
scoreboard.update(score);
},
//
keypress: function (e) {
e = e || window.event; // IE
if (e.which === 49) { // key 1
mediator.players.home.play();
return;
}
if (e.which === 48) { // key 0
mediator.players.guest.play();
return;
}
}
};

:
// !
mediator.setup();
window.onkeypress = mediator.keypress;
// 30
setTimeout(function () {
window.onkeypress = null;
alert(Game over!);
}, 30000);

(observer)
JavaScript. ,
(mouseover, keypress ),
.
, , ,
, .
/.

214

7.

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

1:
, . , paper,
. joe .
paper subscribers, ,
. . - , paper .
-. ,

subscribe() paper.
, paper unsubscribe(),
. paper
publish(), . , - :
subscribers
.
subscribe()
.
unsubscribe()
.
publish()
,
.
type,
(
),
.
, .

215

( )
-.

-, , , visitSub
scribers():
var publisher = {
subscribers: {
any: []
// :
},
subscribe: function (fn, type) {
type = type || any;
if (typeof this.subscribers[type] === undefined) {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
},
unsubscribe: function (fn, type) {
this.visitSubscribers(unsubscribe, fn, type);
},
publish: function (publication, type) {
this.visitSubscribers(publish, publication, type);
},
visitSubscribers: function (action, arg, type) {
var pubtype = type || any,
subscribers = this.subscribers[pubtype],
i,
max = subscribers.length;
for (i = 0; i < max; i += 1) {
if (action === publish) {
subscribers[i](arg);
} else {
if (subscribers[i] === arg) {
subscribers.splice(i, 1);
}
}
}
}
};

,
-, :
function makePublisher(o) {
var i;
for (i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i]===function)
{

216

7.
o[i] = publisher[i];
}
}
o.subscribers = {any: []};
}

paper. , ,
:
var paper = {
daily: function () {
this.publish(big news today);
},
monthly: function () {
this.publish(interesting analysis, monthly);
}
};

paper:
makePublisher(paper);

, -, - joe, :
var joe = {
drinkCoffee: function (paper) {
console.log(Just read + paper);
},
sundayPreNap: function (monthly) {
console.log(About to fall asleep reading this + monthly);
}
};

paper joe ( joe


paper):
paper.subscribe(joe.drinkCoffee);
paper.subscribe(joe.sundayPreNap, monthly);

, joe ,
(any) , ,
(monthly). :
paper.daily();
paper.daily();
paper.daily();
paper.monthly();

joe, :

217


Just read big
Just read big
Just read big
About to fall

news today
news today
news today
asleep reading this interesting analysis

, paper
joe, joe paper.
-, . , ,
, ,
paper ; , joe
.
joe
-. ( ,
.) joe :
makePublisher(joe);
joe.tweet = function (msg) {
this.publish(msg);
};

, ,
,
, ,
joe, readTweets():
paper.readTweets = function (tweet) {
alert(Call big meeting! Someone + tweet);
};
joe.subscribe(paper.readTweets);

, joe - ,
paper :
joe.tweet(hated the paper today);

: Call big meeting!


Someone hated the paper today.
, , http://jspatterns.
com/book/7/observer.html.

2:
. ,

, .

218

7.

, ,
. - Player(),
, ,
scoreboard, . mediator game.
mediator
- . game
;
. , scoreboard
game scorechange.
,
, ,
:
publish(), subscribe() unsubscribe() fire(),
on() remove().
type , .

, , this, .
publisher :
var publisher = {
subscribers: {
any: []
},
on: function (type, fn, context) {
type = type || any;
fn = typeof fn === function ? fn : context[fn];
if (typeof this.subscribers[type] === undefined) {
this.subscribers[type] = [];
}
this.subscribers[type].push({fn: fn, context: context || this});
},
remove: function (type, fn, context) {
this.visitSubscribers(unsubscribe, type, fn, context);
},
fire: function (type, publication) {
this.visitSubscribers(publish, type, publication);
},
visitSubscribers: function (action, type, arg, context) {
var pubtype = type || any,
subscribers = this.subscribers[pubtype],

219


i,
max = subscribers ? subscribers.length : 0;
for (i = 0; i < max; i += 1) {
if (action === publish) {
subscribers[i].fn.call(subscribers[i].context, arg);
} else {
if (subscribers[i].fn === arg &&
subscribers[i].context === context) {
subscribers.splice(i, 1);
}
}
}
}
};

Player() :
function Player(name, key) {
this.points = 0;
this.name = name;
this.key = key;
this.fire(newplayer, this);
}
Player.prototype.play = function () {
this.points += 1;
this.fire(play, this);
};

key, , ,
. ( .) ,
, , newplayer. , -
, play.
scoreboard
.
game ,
scorechange.
keypress, ,
, :
var game = {
keys: {},
addPlayer: function (player) {

220

7.
var key = player.key.toString().charCodeAt(0);
this.keys[key] = player;
},
handleKeypress: function (e) {
e = e || window.event; // IE
if (game.keys[e.which]) {
game.keys[e.which].play();
}
},
handlePlay: function (player) {
var i,
players = this.keys,
score = {};
for (i in players) {
if (players.hasOwnProperty(i)) {
score[players[i].name] = players[i].points;
}
}
this.fire(scorechange, score);
}
};

makePublisher(), , . game (
scorechange). Player.protoype, , , play newplayer,
, :
makePublisher(Player.prototype);
makePublisher(game);

game play newplayer (


keypress ), scoreboard
scorechange:
Player.prototype.on(newplayer, addPlayer, game);
Player.prototype.on(play,
handlePlay, game);
game.on(scorechange, scoreboard.update, scoreboard);
window.onkeypress = game.handleKeypress;

, on()
(scoreboard.update), (addPlayer).
(, game).

221

, ( , ):
var playername, key;
while (1) {
playername = prompt(Add player (name));
if (!playername) {
break;
}
while (1) {
key = prompt(Key for + playername + ?);
if (key) {
break;
}
}
new Player(playername, key);
}

, . http://jspatterns.com/book/7/observergame.html .
, -
,
.
game ;
,
: , scoreboard
scorechange. ( , ),
, . , on() (,
).
, ,
, .
, ,
.



,
JavaScript. , :

222

7.



.
, - Java- . JavaScript . ,
singleton ,
.

, ,
.

,
.


,
-.


, (
) .
-

, .


-
, .


, , , -
( /
).


DOM

JavaScript (ECMAScript), JavaScript . , , , ,

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

.


- :

HTML.

CSS, .

224

8. DOM

JavaScript, .

, ,
,
. , ( HTML),

, ,
.
CSS, ,
. JavaScript,
, .
:
CSS, , .
JavaScript, , ,
, ( href=#) .
(
onclick) style, .
HTML,
.
JavaScript ()
, , . ,
JavaScript, , JavaScript .
JavaScript .
, , .
,
, . ,
. -

DOM

225

, , ,
( ):
//
if (navigator.userAgent.indexOf(MSIE) !== -1) {
document.attachEvent(onclick, console.log);
}
//
if (document.attachEvent) {
document.attachEvent(onclick, console.log);
}
//
if (typeof document.attachEvent !== undefined) {
document.attachEvent(onclick, console.log);
}

, , -,
, , - .
JavaScript, HTML CSS, .

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

DOM
DOM ; JavaScript . , DOM JavaScript.
, JavaScript
DOM. ,
DOM
, JavaScript (, VBScript IE).

226

8. DOM

,
DOM. , :
DOM
DOM
,
length
HTML ( 2)
, , , ,
:
//
for (var i = 0; i < 100; i += 1) {
document.getElementById(result).innerHTML += i + , ;
}
//
var i, content = ;
for (i = 0; i < 100; i += 1) {
content += i + ,;
}
document.getElementById(result).innerHTML += content;

(
) ,

:
//
var padding = document.getElementById(result).style.padding,
margin = document.getElementById(result).style.margin;
//
var style = document.getElementById(result).style,
padding = style.padding,
margin = style.margin;

:
document.querySelector(ul .selected);
document.querySelectorAll(#widget .class);

CSS
DOM, .
( IE 8) , -

DOM

227

, DOM.
JavaScript
, , .
, id= ,
, document.getElementById(myid).

DOM
DOM, , . DOM ,
(
), .
, DOM,
,
DOM .
,
, . , .
, :
//
//
var p, t;
p = document.createElement(p);
t = document.createTextNode(first paragraph);
p.appendChild(t);
document.body.appendChild(p);
p = document.createElement(p);
t = document.createTextNode(second paragraph);
p.appendChild(t);
document.body.appendChild(p);

,
DOM, . DOM , . .
, , (, div).

228

8. DOM

:
var p, t, frag;
frag = document.createDocumentFragment();
p = document.createElement(p);
t = document.createTextNode(first paragraph);
p.appendChild(t);
frag.appendChild(p);
p = document.createElement(p);
t = document.createTextNode(second paragraph);
p.appendChild(t);
frag.appendChild(p);
document.body.appendChild(frag);

, ,
.

. .
,
, , :
var oldnode = document.getElementById(result),
clone = oldnode.cloneNode(true);
// ...
// :
oldnode.parentNode.replaceChild(clone, oldnode);

, , ,
click, mouseover . JavaScript
IE (
9) ,
W3C.
;
,
,
, .

229


. , ,
.
onclick,
, .
JavaScript .
, :
<button id=clickme>Click me: 0</button>

onclick , :
//
var b = document.getElementById(clickme),
count = 0;
b.onclick = function () {
count += 1;
b.innerHTML = Click me: + count;
};

,
,
, . onclick, onclick
.
, addEventListener(). IE 8, attachEvent().
,
( 4), ,
. , :
var b = document.getElementById(clickme);
if (document.addEventListener) {
// W3C
b.addEventListener(click, myHandler, false);
} else if (document.attachEvent) {
// IE
b.attachEvent(onclick, myHandler);
} else {
//
b.onclick = myHandler;
}

230

8. DOM

, ,
myHandler(). , Click
me: 0. , ,

myHandler().
, ,
,
.
, :
function myHandler(e) {
var src, parts;
// -
e = e || window.event;
src = e.target || e.srcElement;
// :
parts = src.innerHTML.split(: );
parts[1] = parseInt(parts[1], 10) + 1;
src.innerHTML = parts[0] + : + parts[1];
//
if (typeof e.stopPropagation === function) {
e.stopPropagation();
}
if (typeof e.cancelBubble !== undefined) {
e.cancelBubble = true;
}
//
if (typeof e.preventDefault === function) {
e.preventDefault();
}
if (typeof e.returnValue !== undefined) {
e.returnValue = false;
}
}

http://jspatterns.com/book/8/
click.html.
:
, , . ,

231

, onclick
window.event .
.
.
,
, ,
window.
:
, W3C (
stopPropagation()), IE (
cancelBubble true).
, . (
)
, , , preventDefault() ( IE,
returnValue false).
, ,
, 7.



, , , . ,
div 10 ,
div
.
div (. 8.1).
http://jspatterns.com/book/8/click-delegate.html.

.8.1. : ,

, :
<div id=click-wrap>
<button>Click me: 0</button>

232

8. DOM
<button>Click me too: 0</button>
<button>Click me three: 0</button>
</div>

,

div. myHandler()
:
, .
,
, div, .
myHandler() ,
nodeName button:
// ...
// -
e = e || window.event;
src = e.target || e.srcElement;
if (src.nodeName.toLowerCase() !== button) {
return;
}
// ...

,
,
, .
, .
JavaScript
, . , YUI3 Y.delegate(),
CSS, ,
, , .
, -
,
. :
Y.delegate(click, myHandler, #click-wrap, button);

YUI ,
:

233

function myHandler(e) {
var src = e.currentTarget,
parts;
parts = src.get(innerHTML).split(: );
parts[1] = parseInt(parts[1], 10) + 1;
src.set(innerHTML, parts[0] + : + parts[1]);
e.halt();
}

http://jspatterns.com/book/8/
click-y-delegate.html.

,
, , ,
. , ,
.
, ,
. ,
.
JavaScript
, setTimeout()
(web workers), .

setTimeout()
setTimeout() ,
1 . ,
.
- 1 ( 0 )
. 0 , . Inter
net Explorer, , , , 15 .

234

8. DOM

(web workers)
, :
(web workers).
. ,
, , my_web_worker.js,
(),
:
var ww = new Worker(my_web_worker.js);
ww.onmessage = function (event) {
document.body.innerHTML +=
<p>message from the background thread: + event.data + </p>;
};

,
1e8 (1 8 ):
var end = 1e8, tmp = 1;
postMessage(hello there);
while (end) {
end -= 1;
tmp += end;
if (end === 5e7) { // 5e7 1e8
postMessage(halfway there, `tmp` is now + tmp);
}
}
postMessage(all done);

postMessage(),
onmessage, .
onmessage data, .
, ( )
ww.postMessage(),
onmessage.
:
message from the background thread: hello there
message from the background thread: halfway there,
`tmp` is now 3749999975000001
message from the background thread: all done

235


-
. -,
. JavaScript.

XMLHttpRequest
XMLHttpRequest (-), HTTP- JavaScript. ,
:
1. XMLHttpRequest ( XHR ).
2. ,
.
3. .
:
var xhr = new XMLHttpRequest();

IE 7 XHR ActiveX, .

readystatechange:
xhr.onreadystatechange = handleResponse;

,
open() send(). open() HTTP-
(: GET, POST) URL. send()
, POST,
, GET. open() , .
, .
, , , , true:
xhr.open(GET, page.html, true);
xhr.send();

236

8. DOM

, ( http://jspatterns.com/
book/8/xhr.html):
var i, xhr, activeXids = [
MSXML2.XMLHTTP.3.0,
MSXML2.XMLHTTP,
Microsoft.XMLHTTP
];
if (typeof XMLHttpRequest === function) {
// XHR
xhr = new XMLHttpRequest();
} else {
// IE 7
for (i = 0; i < activeXids.length; i += 1) {
try {
xhr = new ActiveXObject(activeXids[i]);
break;
} catch (e) {}
}
}
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return false;
}
if (xhr.status !== 200) {
alert(Error, status code: + xhr.status);
return false;
}
document.body.innerHTML += <pre> + xhr.responseText + <\/pre>;
};
xhr.open(GET, page.html, true);
xhr.send();

:
IE 6 XHR .
ActiveX, , ,
try-catch.
readyState
xhr. 0
4, 4 . ,
readystatechange.

237


status xhr. HTTP, 200 (OK) 404 ( ).
200
(
, ).
,
XHR , . (
, ), ,
.

JSONP
JSONP (JSON with padding JSON )
.
XHR, , -
, ,
.
XHR :
XML ()
HTML ( )
JSON ( )

JSONP ,
JSON, ,
.
URL JSONP :
http://example.org/getdata.php?callback=myHandler
getdata.php .
callback JavaScript, .
URL <script>, :
var script = document.createElement(script);
script.src = url;
document.body.appendChild(script);

238

8. DOM

JSON, .
, .
:
myHandler({hello: world});

JSONP: -
JSONP
-, () . 1 9,

JSONP (.8.2).
http://jspatterns.
com/book/8/ttt.html.

.8.2. -, JSONP

:
(
):
<button id=new>New game</button>
<button id=server>Server play</button>

id. :
<td id=cell-1>&nbsp;</td>
<td id=cell-2>&nbsp;</td>

239

<td id=cell-3>&nbsp;</td>
...

ttt:
var ttt = {
// ,
played: [],
// ,
get: function (id) {
return document.getElementById(id);
},
//
setup: function () {
this.get(new).onclick = this.newGame;
this.get(server).onclick = this.remoteRequest;
},
//
newGame: function () {
var tds = document.getElementsByTagName(td),
max = tds.length,
i;
for (i = 0; i < max; i += 1) {
tds[i].innerHTML = &nbsp;;
}
ttt.played = [];
},
//
remoteRequest: function () {
var script = document.createElement(script);
script.src = server.php?callback=ttt.serverPlay&played= +
ttt.played.join(,);
document.body.appendChild(script);
},
// ,
serverPlay: function (data) {
if (data.error) {
alert(data.error);
return;
}
data = parseInt(data, 10);
this.played.push(data);
this.get(cell- + data).innerHTML = <span class=server>X<\/span>;
setTimeout(function () {

240

8. DOM
ttt.clientPlay();
}, 300); //
},
//
clientPlay: function () {
var data = 5;
if (this.played.length === 9) {
alert(Game over);
return;
}
// 1-9,
//
while (this.get(cell- + data).innerHTML !== &nbsp;) {
data = Math.ceil(Math.random() * 9);
}
this.get(cell- + data).innerHTML = O;
this.played.push(data);
}
};

ttt ttt.played , , . :
ttt.serverPlay({error: Error description here});

, JSONP
, ,
. :
ttt.serverPlay(3);

3 3 , . , JSON;
, .




. JavaScript (iframe) URL src.

JavaScript

241

URL ,
(iframe).

.

src URL :
new Image().src = http://example.org/some/page.php;

; , , , ,
.
, (: )
GIF 11. HTTP 204 No Content.
.

JavaScript
JavaScript , , . .
High
Performance Web Sites Even Faster Web Sites, OReilly.


,
,
,
HTTP . Java
Script , .
, jQuery. .js.
, jQuery,
. ,
,
45 .
, ,
(23 ),
HTTP
. ,
.

242

8. DOM

, ,
, .
:
,
,
cat Linux/UNIX:
$ cat jquery.js jquery.quickselect.js jquery.limit.js > all.js


.

: , , ,
, , .
, all_20100426.js .
,
.


2 .
.
, , .
,
, , .
50%
.
.

gzip .
,
, .htaccess Apache.

JavaScript

243

.htaccess, -,
:
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml
application/JavaScript application/json

70%. , , , 15%
, .

Expires
,
.
Expires.
, .htaccess:
ExpiresActive On
ExpiresByType application/x-JavaScript access plus 10 years

,
, ,
, .

CDN
CDN Content Delivery Network ( ). ( ) ,
,
, ,
URL.
CDN, :
Google , , ,
CDN,
.
Microsoft jQuery
Ajax.
Yahoo! YUI
CDN.

244

8. DOM


<script> JavaScript ,
src:
// 1
<script>
console.log(hello world);
</script>
// 2
<script src=external.js></script>

, ,
-.
,
<script>:
language=JavaScript

JavaScript .
language ,
, JavaScript. ,
.
type=text/JavaScript
, HTML4
XHTML1, ,

JavaScript. HTML5 . , .
defer
( async,
HTML5) , , ,
.
.

<script>
<script> .
,
<script>, , -

245

, . ,
.
, <script> , </body>.
.

.
:
<!doctype html>
<html>
<head>
<title>My App</title>
<!-- -->
<script src=jquery.js></script>
<script src=jquery.quickselect.js></script>
<script src=jquery.lightbox.js></script>
<script src=myapp.js></script>
</head>
<body>
...
</body>
</html>

:
<!doctype html>
<html>
<head>
<title>My App</title>
<script src=all_20100426.js></script>
</head>
<body>
...
</body>
</html>

:
<!doctype html>
<html>
<head>
<title>My App</title>
</head>
<body>
...

246

8. DOM
<script src=all_20100426.js></script>
</body>
</html>

HTTP
HTTP
. .
-, ,
, .
, <head>
, . , , :
<!doctype html>
<html>
<head>
<title>My App</title>
</head>
<!-- end of chunk #1 -->
<body>
...
<script src=all_20100426.js></script>
</body>
</html>
<!-- end of chunk #2 -->

Java
Script <head>, .
, :
<!doctype html>
<html>
<head>
<title>My App</title>
<script src=all_20100426.js></script>
</head>
<!-- end of chunk #1 -->
<body>
...
</body>
</html>
<!-- end of chunk #2 -->

, .

247

, :
<!doctype html>
<html>
<head>
<title>My App</title>
</head>
<body>
<div id=header>
<img src=logo.png />
...
</div>
<!-- end of chunk #1 -->
... ...
<!-- end of chunk #2 -->
<script src=all_20100426.js></script>
</body>
</html>
<!-- end of chunk #3 -->

JavaScript. HTML

, JavaScript.
JavaScript, , .

<script>

, JavaScript
, . , :
XHR
eval(). -, ,
eval(),
.
defer async,
.
<script>.
. JSONP

248

8. DOM

<script>, src
.
JavaScript ,
:
var script = document.createElement(script);
script.src = all_20100426.js;
document.documentElement.firstChild.appendChild(script);

, , main.js.
main.js ,
, ,
,
, .
,
, ,
.
, . .

:
var mynamespace = {
inline_scripts: []
};

inline_scripts. :
// :
// <script>console.log(I am inline);</script>
// :
<script>
mynamespace.inline_scripts.push(function () {
console.log(I am inline);
});
</script>

, :
var i, scripts = mynamespace.inline_scripts, max = scripts.length;
for (i = 0; i < max; max += 1) {
scripts[i]();
}

249

<script>
<head> , , <body> ( JSONP).
<head>
documentElement,
<html>, <head>:
document.documentElement.firstChild.appendChild(script);

:
document.getElementsByTagName(head)[0].appendChild(script);

,
, ,
,
.
<head>, <body> document.body
, <body>:
document.body.appendChild(script);

, , , ,
<script>. <script> (
), .
insertBefore() <script> <script>
:
var first_script = document.getElementsByTagName(script)[0];
first_script.parentNode.insertBefore(script, first_script);

first_script <script>, , script <script>, .


, load.
:
, .
, , -

250

8. DOM

, ,
.
,
. ,
, .
JavaScript
<script>
:
... ...
<!-- end of chunk #2 -->
<script src=all_20100426.js></script>
<script>
window.onload = function () {
var script = document.createElement(script);
script.src = all_lazy_20100426.js;
document.documentElement.firstChild.appendChild(script);
};
</script>
</body>
</html>
<!-- end of chunk #3 -->

,
, , ,
( , XHR ) ,
.


JavaScript, ,
.
, ?
, .
XHR ,
. , XHR
,
?

251

.
require(),
, , ,
.
require() ,
:
require(extra.js, function () {
functionDefinedInExtraJS();
});

, .
<script>. , , - , :
function require(file, callback) {
var script = document.getElementsByTagName(script)[0],
newjs = document.createElement(script);
// IE
newjs.onreadystatechange = function () {
if (newjs.readyState === loaded || newjs.readyState === complete){
newjs.onreadystatechange = null;
callback();
}
};
//
newjs.onload = function () {
callback();
};
newjs.src = file;
script.parentNode.insertBefore(newjs, script);
}

:
IE readystatechange
, readyState
. .
Firefox, Safari Opera load, onload.
Safari 2. , -

252

8. DOM

- ,
. , , .
( )
ondemand.js.php, :
<?php
header(Content-Type: application/JavaScript);
sleep(1);
?>
function extraFunction(logthis) {
console.log(loaded and executed);
console.log(logthis);
}

require():
require(ondemand.js.php, function () {
extraFunction(loaded from the parent page);
document.body.appendChild(document.createTextNode(done!));
});

done!. http://jspatterns.
com/book/7/ondemand.html.

JavaScript
, , . , , ,
. ,
, , .
<script>. ,
. , JavaScript,
,
, , DOM.
, ;
CSS .

253

IE ,
:
new Image().src = preloadme.js;

<script>
<object> data URL :
var obj = document.createElement(object);
obj.data = preloadme.js;
document.body.appendChild(obj);

, 0 width height.
preload() ,
( 4), :
var preload;
if (/*@cc_on!@*/false) {
// IE
preload = function (file) {
new Image().src = file;
};
} else {
preload = function (file) {
var obj = document.createElement(object),
body = document.body;
obj.width = 0;
obj.height = 0;
obj.data = file;
body.appendChild(obj);
};
}

:
preload(my_web_worker.js);

, ,
. , , , typeof
Image function,
. , new Image(), ,
, , -

254

8. DOM

, ,
.

.
, navigator.userAgent, .
:
var isIE = /*@cc_on!@*/false;

isIE false
( ), IE
- ! .
IE:
var isIE = !false; // true

, . , , , .
,
(, ), , .



JavaScript,
, , ,
, .
:
(HTML: , CSS: , JavaScript: ), JavaScript,
,
. (
, .)
DOM , DOM , DOM .
, , , -

255

.
setTimeout()
(web workers), .

XHR, JSONP , .
, JavaScript
: , (
85%), CDN
Expires, .
, , :
<script>, , HTTP. ,
,
, , .


C
[] ( ),
, 43
{} ( ),
, 47
; ( ), JavaScript, 48

A
Activation Object ( ), 21
addEventListener(), , 229
API, , 54
apply(), , 173
arguments.callee, , 72, 107
Array(),
isArray(), , 75
typeof, 74
, 73
, 73

B
Boolean(), , 79

C
call(), , 173
CDN (Content Delivery Network, ), 243
@class, (YUIDoc), 57
constructor, , 23
@constructor, (YUIDoc), 58
const, , 142

D
Date(), , 66
delete, , 32
dir(), , 26
<div>, , 231
document,
forms, , 36
getElementById(), , 227

getElementsByClassName(), , 36
getElementsByName(), , 36
getElementsByTagName(), , 36
images, , 36
links, , 36
DOM API, 145

E
ECMAScript 5, , 24
, 169
, 24
, 22
, 24, 107
Error(), , 80
eval(),
, 43
Expires, , 243

F
for-in, , 38
for, , 36
var, 37
Function(),
bind(), , 176
, 44
, 84

G
Google Closure Compiler,
JavaScript, 61, 103

H
hasOwnProperty(), , 39
.htaccess, , 242
HTMLCollection, , 36
HTTP,
, 246

I
<iframe>, , 240
instanceof, , 165

257

J
javadoc, , 54
JavaScript,
, 22
-, 21
, 252
, 241
jQuery,
parseJSON(), , 76
, 145
JSDoc Toolkit, , 54
JSLint,
, 25
, 62
JSON,
parse(), , 44, 76
stringify(), , 77
, 75
JSONP (JSON with padding, JSON ), 237

, 186
, 67
, 66
onclick, , 229

P
@param, (YUIDoc), 57
__parent__, Mozilla Rhino,
124
parseInt(), , 45
@property, (YUIDoc), 58
prototype, , 23, 41
, 126
, 160
, 150
, 23
, 41

R
RegExp(), , 77
@return, (YUIDoc), 57

klass(), , 163
length,
, 37
, 79
load, , 94
log(), , 26

<script>,
, 247
, 249
, 244
setTimeout(), , 44, 233
String(), , 66, 79
switch, , 42
SyntaxError(), , 80

method(), , 145
@method, (YUIDoc), 57

that, , 71
this,
, 70
, 174
, 68
, 93
, 68
, 33
throw, , 80
@type, (YUIDoc), 58
TypeError(), , 80
typeof, , 74

N
name, , 87
@namespace, (YUIDoc), 57
new,
, 149
, 179
, 70
Number(), , 79
, 186
-, 79

O
Object(),
toString(), , 75

V
var,
, 33
, 32
delete, 32

258
, 32
for, 37
, 34
, 31

W
window, , 30, 33

X
XMLHttpRequest, , 235

Y
Yahoo! YUICompressor, , 61
YAHOO, (YUI2),
121
YQL, -, 206
YUIDoc, , 54, 55
YUI (Yahoo! User Interface Yahoo!), , 55

, 85

, 21

, 224
, 95

, 22
<script>, 244

eval(), 43

, 163

, 95
, 101


,
100
-, 69
, 160
,
, 104


, 33
this, 70
window, 30, 33
, 30
, 118

, 33
, 32
var, 32
, 33
, 133
,
99
, 30, 118
, 30
, 34
, 30
, 30

, , 189
, 231
API, 54, 59

,
new, 179
, 178
, 181
, 180

, 173

-, , 238
, 119,
133
, 119, 133
-, 85
, 133
, , 187

259

, 109, 112
, , 43

, 160
, 158
, 154
, 149
, 150
, 159

, 150

JavaScript, 22
, 163
new, 149
, 53
, 60

, 69
, 51
, 72
,
133
this, 68
, 150
, 132
, 162
, 136
, 51, 71
, 66
, 154, 160

, , 173
, 241
, , 106

, 173
prototype, 126
, 127
, 127, 138
-, 79
, 22, 64
, 124, 129
, 138
, 79
, 123, 140
, 144
, 157

, 135
, 133
, 121, 129
, 129
, 132
, 129

Object(), , 64
, 73

, 64
, 126
, 77
, 86
, 84

, , 213
, 213
, 214

, 217
, 148
, 150
, 148
, 169
, 157
JavaScript, 23
, 171
, 166
,
102
, 98,
129
, 98
, 101
, 100

260
, 98
, 99
, 129
, 98
, 101

, 240
, 229
, 94
, 198
, 203

, 127
, 138
, 138
- , 21
, 21, 22
init(), , 102
, 30, 33, 70
, 173
, 102
, 79
, 22
, 22
, 80
, 170

, 67
, 22
, 21
, 66
, 108
, 123, 129
, 65
-, 142
, 121
, 129
, 224

, 224

, 214
-,
210


name, 85, 87
, 249
, 199
(
), 46
,
60

, 84
, 31
, 21
, 34
, 42
, 52
, 38
, 170

klass(), , 163
, 148
, 173
,
169
, 150
, 171
,
160

, 158
, 154
,
150

, 159
, 149

var, 32
, 31
, 31
, 34
, 88
, 224
, , 209

JavaScript, 252

261



, 129
, 124
, 109
(
), 49

, 195
, 195
-, , 199
, 209
, 199
, 200
, 161, 163
, 163
, 117
, 30, 118
, 129
, 119
, 117


, 158
, 126
, 23
, 159
, 39

, 112
, 112

DOM, 225
JavaScript,
241
CDN, 243
Expires, 243
, 241
, 242
, 223

parseInt(), , 45
switch, , 42
API, 54
JSLint, 62
, 53
, 60
, 42
, 223
prototype, 41

, 60
, 51
, 46

, 28

, 30
for, 36
for-in, 38

, 96

delete, 32
prototype, 126
, 169
, 80
, 21, 64
, 138
, 39
, 123
, 171
, , 60

, 73
, 66
,
77
, 171
, 22
, 228
, 231
, 51
, 52
, 51, 71
, 52
, 52
, 52
, 52
, 46
, 46
, 49
, 47
, 193
, 23
, 22
, 138
, 138
, 138
, 140

262
(), 244
<script>, , 244
, 250
, 249
, 247
, 252

HTTP, 246
, , 194
, , 24
, , 233
setTimeout(), , 233
(web workers),
234

, 235
XMLHttpRequest, , 235
JSONP, 237
, 241

, , 184
, , 198
(web workers), 234
, 227
HTTP,
246

name, , 87
prototype, , 41
, 54
, 34
, 95
, 51, 68
, 83
, 109, 112
, 98
, 85

, 84
, 89
, 95
, 92
, 90
, 94
, 89
, 94
, 90
, 30


, 88
, 112
, 96
, 52
, 30
, 110
, 106
-
, 85
, 86
,
98
, 85
-
, 150
, 123
, 68

, 236
-
, 85
, 88
, 86
, 85

, 144

, 110
, 140
, 140

, 129
,
127
, 123

, 19
, 19
new, 70
API
, 95
, 112
, 108
, 89

263



,
, 104
, 102
,
98
, 199

, 21

, 106

, 131
, 127

, 189
, 178
, 187
, 213
, 20, 178
, 20
, 209
-, 199
, 194
, 184
, 198

, 96


method(), , 145
,
119, 133
, 131
,
127
, 129
-, 142
, 121
, 117
, 138
, 144
, 123

, 126
, 126
-, 123

, 124
, 124
, 123

, 181
, 180

- -
Books.Ru
ISBN 978-5-93286-208-7,
JavaScript. - Books.Ru
. -
, .
,
- (piracy@symbol.ru),
.