JavaScript as Development platform gives overview of JavaScript as Runtime and Programming Language. From this presentation you can find out more about advanced language features and usage patterns.
2. CONVENTIONS
SOURCE CODE
BAD PRACTICE LEGACY CODE
var global = 10; function factorial(x) {
if (x <= 1) {
function foo() { return 1;
global++; }
}
return x * arguments.callee(x - 1);
}
GOOD PRACTICE
(function () {
var local = 10;
CODE SNIPPET
function foo() { function foo() {
local++; console.log(‘foo’);
} }
})();
4. SOURCES OF CONFUSION
JAVA PREFIX
Completely independent from Java
Has syntax similarities
5. SOURCES OF CONFUSION
SCRIPT POSTFIX
Doesn’t mean that JS isn`t real
programming language
Full-fledged Object Oriented language
6. SOURCES OF CONFUSION
WEAK LEARNING SOURCES
Standard has complicated structure makes it hard to
read and understand
Almost all books are universally bad
Internet full of bad advices and practices
8. WHAT IS Javascript
A scripting language designed as
lightweight alternative to Java for Web
9. history
1992
James Gosling at Sun Microsystems
has been working on superior
language to C++ called Oak
10. history
1992
Microsoft released Windows 3.1
and preview of Microsoft
Windows NT for developers
11. history
1995
Oak has failed as a language for
interactive television and has been
repurposed for Web. At this time
language has been renamed to Java.
12. history
1995
Sun Microsystems officially
announced HotJava browser with
support of Java-applets.
13. history
1995
Web becomes hot and Microsoft
ships Internet Explorer 1.0 and
Internet Explorer 2.0 few month later
14. history
1995
Brendan Eich at Netscape
Communication Corporation begun
working on lightweight and simple
alternative to Java for Web browser
15. history
1995
Later on Netscape released
Netscape Navigator 2.0 with support
of LiveScript and Java-applets
16. history
1995
Anticipated by opportunity to free
Web from Microsoft, Sun and Netscape
formed the alliance
As the result LiveScript has been
renamed to JavaScript
17. history
1996
Microsoft reverse-engineered
JavaScript and named it JScript to
avoid trademark issues with Sun
18. history
1996
Microsoft released Internet Explorer 3
with support of JScript
19. history
1996
To prevent Microsoft from mutating
the language, Sun and Netscape made
their way to ECMA to standardize the
language
20. history
1996
Sun and Netscape have failed and
Microsoft gathered full control on
standardization process. Microsoft
insisted on preserving some design
errors in the language
21. history
1998
ECMA International introduces
ECMA-262 1st + 2nd edition of
JavaScript language
22. VIEW STANDARD
STANDARD
ECMA 262
ECMA-262 is active standard that defines JavaScript
Uses term ECMAScript
Structured in a way that makes it hard to read
23. VIEW STANDARD
STANDARD
TIMELINE
1997 1998 1999 2000-2009 2009 Future
1st edition 2nd edition 3rd edition 4th edition 5th edition Harmony edition
June June December December
33. DESIGN PRINCIPLES
OBJECT ORIENTED LANGUAGE
OBJECT ORIENTED CODE SNIPPET
function Plane(mass) {
this.mass = mass;
};
var lightPlane = new Plane(10),
heavyPlane = new Plane(1000);
34. DESIGN PRINCIPLES
Functional language
FUNCTIONAL CODE SNIPPET
var
combine = function (a, b) {
return function () {
a();
b();
};
},
combined = combine(
function () {
console.log('Logging');
},
function () {
alert('Alerting');
}
);
combined();
35. DESIGN PRINCIPLES
OBJECT ORIENTED LANGUAGE
Imperative CODE SNIPPET
function bound(x, min, max) {
var value = x;
value = Math.min(value, max);
value = Math.max(value, min);
return value;
}
36. WHAT IS Javascript
A programming language that is more
than just a Web toy
37. Runtime
Host environments
JavaScript executes in a
JAVASCRIPT ENGINE
context of Engine
Host environment
powers JavaScript Engine
HOST SPECIFIC API
39. HOST ENVIRONMENTS
RESPOSIBILITIES
REPOSNSIBLE FOR NOT RESPONSIBLE FOR
Input/Output Code execution
Graphics Memory management
Storage
Networking
Host specific API
41. HOST ENVIRONMENTS
WEB BROWSER
WEB BROWSER HOST
JAVASCRIPT ENGINE
HOST SPECIFIC API
DOCUMENT OBJECT MODEL BROWSER Object MODEL
42. WEB BROWSER
DOCUMENT OBJECT MODEL
Representation of document as
objects hierarchy
Language & browser independent
Standardized by W3C
Revisions are called DOM levels
43. WEB BROWSER
BROWSER Object MODEL
API for interfacing native browser
functionality
Deals with windows and frames
All functions and object starting at
window
No corresponding standard
47. ENGINE RUNTIME
Script distribution
Script are consumed as plain text
Interpreted or compiled in-place
*.js is a format for script files
Mime-type:
Officially: application/javascript
Practically: text/javascript or no MIME type at all
48. ENGINE RUNTIME
Script compression
WHY? techniques
Less traffic consumption GZip
Faster load time Minification
Obfuscation
50. Static inclusion
Script tag
Script can be put anywhere
on a page with <script> tag
CODE SNIPPET
<script src="path/to/script.js" type="text/javascript"></script>
51. Static inclusion
Type attribute
<script> tag should have matching </script> tag, except
when document has application/xhtml+xml MIME type
BAD PRACTICE
<script src="path/to/script.js" type="text/javascript"/>
GOOD PRACTICE
<script src="path/to/script.js" type="text/javascript"></script>
53. static inclusion
Inline scripts
<script> tag supports inlining, but generally
it is considered as bad practice
CODE SNIPPET
<script>
console.log('Inline script');
</script>
54. static inclusion
Execution ordering
Scripts attached in that way execute in
order, even if script2 got loaded sooner
CODE SNIPPET
<script src="path/to/script1.js" type="text/javascript"></script>
<script src="path/to/script2.js" type="text/javascript"></script>
55. static inclusion
Execution ordering
Same holds for inline scripts
CODE SNIPPET
<script src="path/to/script1.js" type="text/javascript"></script>
<script>
console.log('Inline script');
</script>
56. static inclusion
rendering
Script loading and execution blocks page
rendering
CODE SNIPPET Script.js
<script src="link/to/script.js"></script> var link =
document.getElementById('link');
<a id="link" href="url/to/somewhere.html">Link</a>
console.log(link != null); // false
57. static inclusion
rendering
Consider moving script to the bottom of
the document
Not every script can be moved
GOOD PRACTICE
<body>
<div class="page-content">Ipsum lerrra conde ir salle.</div>
<script src="js/script1.js"></script>
<script src="js/script2.js"></script>
</body>
58. static inclusion
Asyncloading
Scripts can be loaded asynchronously
using async attribute
Script loading does not block rendering
CODE SNIPPET
<script src="link/to/script.js" async></script>
59. Static inclusion
ASYNC loading
Ordering will not be preserved
No execution time guarantee
All async scripts are guaranteed to execute
sometime before window load event
CODE SNIPPET
<script src="link/to/script1.js" async></script>
<script src="link/to/script2.js" async></script>
60. Static inclusion
defer loading
Scripts can be loaded in defer manner
using defer attribute
Script loading does not block rendering
CODE SNIPPET
<script src="link/to/script.js" defer></script>
61. STATIC INCLUSION
defer loading
Ordering will be preserved
Scripts are guaranteed to start execution
right before DOMContentLoaded event
CODE SNIPPET
<script src="link/to/script1.js" defer></script>
<script src="link/to/script2.js" defer></script>
62. static INCLUSION
Async+deferloading
Causes legacy browsers to fallback to defer if
async is not supported
Modern browsers treat defer + async as async
CODE SNIPPET
<script src="link/to/script1.js" async defer></script>
63. static INCLUSION
LOADING TIMELINE
Scripting
<script>
HTML Parser
Scripting
<script async>
HTML Parser
Scripting
<script defer>
HTML Parser
Networking Execution Parsing
65. DYNAMIC INCLUSION
asynchronous
Asynchronous
Script ordering will not be preserved
CODE SNIPPET
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.src = 'script.js';
head.appendChild(script);
66. Dynamic inclusion
asynchronous
Asynchronous
Script ordering will be preserved
Older browsers require tricky solutions
CODE SNIPPET
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.async = false;
script.src = 'script.js';
head.appendChild(script);
67. DYNAMIC INCLUSION
DEFERRED
Deferred
Has no effect when loaded via DOM API
CODE SNIPPET
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.src = 'script.js';
script.defer = 'defer';
head.appendChild(script);
69. VIEW More
script INCLUSION
Parallel loading
Number of parallel HTTP connections per
hostname is limited
Typically varies from 2 ~ 6
Consider CDN and subdomain usage
71. ENGINE RUNTIME
Strict EXECUTION Mode
Allows to opt-out to strict variant of
JavaScript
Intended to correct initial design errors
Prohibits usage of error-prone and insecure features
Standardized in ECMA 262-5
72. STRICT Mode
activation
Activated with a Use Strict Directive in a
Directive Prologue
CODE SNIPPET
'use strict';
var f = function () {
console.log('Execution under strict mode');
};
f();
73. STRICT Mode
scoping
CODE SNIPPET
Applied to a code unit 'use strict';
eval = 10; // SyntaxError
To a Function
var f = function () {
To a code file eval = 20; // SyntaxError
};
Affects all inner contexts
CODE SNIPPET
Defined lexically (statically) eval = 10; // 10
var f = function () {
'use strict';
eval = 20; // SyntaxError
};
74. STRICT Mode
inheritance
Directly Evaled code inherits Strict Mode
Indirectly Evaled code doesn`t inherit
Strict Mode
Functions created via new Function ()
dont inherit Strict Mode
76. STRICT Mode
restrictions
Reserved words
CODE SNIPPET
Implements Protected "use strict";
var let = 10; // SyntaxError
Interface Public
Let Static
Package Yield
Private
77. STRICT Mode
restrictions
Octal literals are not allowed
CODE SNIPPET
"use strict";
var x = 010; // SyntaxError
Assignment to an undeclared identifier
CODE SNIPPET
"use strict";
a = 10; // ReferenceError
78. STRICT Mode
restrictions
Assignment to read-only property
CODE SNIPPET
"use strict";
var foo = Object.defineProperties({}, {
bar: {
value: 10,
writable: false // by default
},
baz: {
get: function () {
return "baz is read-only";
}
}
});
foo.bar = 20; // TypeError
foo.baz = 30; // TypeError
79. STRICT Mode
restrictions
Shadowing of inherited read-only properties
CODE SNIPPET
"use strict";
var foo = Object.defineProperty({}, "x", {
value: 10,
writable: false
});
var bar = Object.create(foo);
bar.x = 20; // TypeError
80. STRICT Mode
restrictions
Eval and arguments
Cannot appear as variable declaration of function name
CODE SNIPPET
"use strict";
// SyntaxError in both cases
var arguments;
var eval;
// also SyntaxError
function eval() {}
var foo = function arguments() {};
81. STRICT Mode
restrictions
Eval and arguments
Not allowed as argument names Not assignable
CODE SNIPPET CODE SNIPPET
"use strict"; (function (x) {
alert(arguments[0]); // 30
// SyntaxError arguments = 40; // TypeError
function foo(eval, arguments) {} })(30);
84. STRICT Mode
restrictions
With statement this value
CODE SNIPPET Null no longer coerced to window
"use strict";
CODE SNIPPET
"use strict";
// SyntaxError
with ({a: 10}) { function foo() {
alert(a); console.log(this); // undefined
} }
foo();
85. STRICT Mode
restrictions
this value
Null and undefined are no longer Primitives are not converted to
coerced to window wrapper objects
CODE SNIPPET CODE SNIPPET
"use strict"; "use strict";
function foo() { Number.prototype.test = function () {
console.log(this); // undefined console.log(typeof this); // number
} };
foo(); (1).test(); // number
86. STRICT Mode
restrictions
this value CODE SNIPPET
"use strict";
Helps to avoid missing new
function A(x) {
keyword issues this.x = x;
}
// forget "new" keyword,
// error, because undefined.x = 10
var a = A(10);
var b = new A(10); // OK
87. STRICT Mode
Usage guidelines
Do not apply strict mode to whole script
file blindly
Will not work when concatenated with some other script
Can break other scripts if after concatenation put first
Evaled code will inherit Strict Mode
Consider wrapping your scripts with self-
calling function
88. WHAT IS Javascript
JavaScript is a language that has
simple but flexible type system
89. Type system
essentials
Class-free type system
Loose typing
Everything is an object
Technically JavaScript has primitive types but they
can be programmed as real objects
90. Type system
essentials
Two groups of types
Primitive types
Object types
Primitives are not real objects
Some primitives has object wrapper
91. Type system
Types
Primitive types Object types
Number Object
String Array
Boolean Function
null RegExp
undefined Date
92. numbers
essentials
Single type represents integer and floating
point numbers
IEEE 754 64 bit numbers
Be aware of floating point errors
0.1 + 0.2 !== 0.3
Can be avoided by scaling
93. numbers
runtime
Runtime type Number object wrapper
CODE SNIPPET CODE SNIPPET
var foobar = 0.5; var a = 10;
typeof foobar; // "number" var b = new Number(a);
var foobar = 1;
typeof foobar; // "number" console.log(typeof b); // object
95. numbers
nan
Paradoxical type
CODE SNIPPET
var foobar = NaN;
typeof foobar; // "number"
Watch out, easy to overwrite!
CODE SNIPPET
var NaN = "string";
typeof NaN; // "string"
96. numbers
nan
Getting NaN
CODE SNIPPET
var foobar = "string" * 2,
bar = "string" / 2;
var foo = +"string",
barfoo = +[1, 2, 3],
foobar2 = undefined – 2;
97. strings
essentials
Unicode UTF-16
Built-in string manipulation routines don't take
surrogate pairs into account
Immutable
Zero-based indexing
No dedicated Char type
99. strings
runtime
Runtime type String object wrapper
CODE SNIPPET CODE SNIPPET
var foobar = "variable types"; var a = 'foo';
typeof foobar; // "string" var b = new String(a);
console.log(typeof b); // object
100. boolean
essentials
Two possible predefined values
true
false
Generally Boolean produced by comparisons
a === 1
Any value can be converted to Boolean
101. Boolean
Falsyvalues
CODE SNIPPET
undefined
var falsyValue = 0;
if (!falsyValue) {
null
alert("falsy value!");
}
0 var falsyValue = "";
-0 if (!falsyValue) {
alert("falsy value!");
NaN }
Empty string var falsyValue = NaN;
if (!falsyValue) {
alert("falsy value!");
}
102. Boolean
runtime
Runtime type Boolean object wrapper
CODE SNIPPET CODE SNIPPET
var foobar = true; var a = true;
typeof foobar; // "boolean" var b = new Boolean(a);
console.log(typeof b); // object
110. Object originators
Host objects
Host objects
Host objects are objects that are
supplied to JavaScript by the browser
environment
Examples of these are window,
document, forms, etc
Poorly defined
111. Object originators
Native objects
NATIVE OBJECTS
Native objects are those objects
supplied by JavaScript runtime
Examples of these are String,
Number, Array, Image, Date, Math,
etc
Be very cautious extending these
118. object
prototype
Prototype links object with another object
Internal [[prototype]] field
Set at creation based on Function.prototype value
Simple form of inheritance
No schema (classes) involved
Object inherits directly from another object
121. prototype
Property resolution
Example
toString is not declared in object but rather in
Object.prototype
CODE SNIPPET
var object = {};
console.log(object.toString());
122. prototype
inspection
Undocumented field Constructor`s prototype
BAD PRACTICE CODE SNIPPET
var object = {}; var object = {};
console.log(object.__proto__); console.log(object.constructor.prototype);
getPrototypeOf
CODE SNIPPET
var object = {};
console.log(Object.getPrototypeOf(object));
123. object
reflection
for in hasOwnProperty
CODE SNIPPET CODE SNIPPET
var obj = {
property: "foobar", for (var i in obj) {
method: function() {} if (obj.hasOwnProperty(i)) {
}; alert("The value of key " + i +
for (var i in obj) { " is " + obj[i]);
alert("The value of key " + i +" is " + }
obj[i]); }
}
124. object
reflection
in __count__
CODE SNIPPET BAD PRACTICE
var obj = { var obj = {
a: 10 property: "foobar",
}; method: function() {}
};
var hasProperty = ('a' in obj); obj.__count__; // 2
125. array
essentials
Ordered collection of values
Zero-based 32bit indexing
Dynamic
No need for memory reallocation
Specialized form of objects with length
property
131. operators
operator =
―=―
Multiple assignment
Assignment order is from right to left
CODE SNIPPET
var foobar = 1;
var foo = 2;
var bar = foo = foobar = 3; // bar == 3, foo == 3, foobar == 3
132. Operators
operator +
String concatenation
CODE SNIPPET
var foobar = "This " + "is " + "a variable.";
Casting to number
CODE SNIPPET
var foobar = +true; // 1
var foobar = +false; // 0
134. Operators
operators += and ++
Addition Casting to string
CODE SNIPPET CODE SNIPPET
var foobar = 1; var foobar = "1";
foobar += 1; // 2 foobar += 5; // "15"
Casting to number
CODE SNIPPET
var foobar = "5";
foobar++;
typeof foobar; // "number"
135. Operators
operators += and ++
Multiple assignments
CODE SNIPPET
var foo = 1;
var bar = 2;
foo += bar += 3; // foo == 6; bar == 5;
CODE SNIPPET
var foo = "1";
var bar = "2";
foo += bar += " is a string";
// foo == "12 is a string;
// bar == "2 is a string";
136. Operators
operators -= and --
Decrement
CODE SNIPPET
var foobar = 1;
foobar -= 1; // 0
-= does not behave like +=
CODE SNIPPET CODE SNIPPET
var foobar = "5";
var foobar = "1"; foobar--;
foobar -= 5; // -4 (number) // 4
typeof foobar; // "number"
137. Operators
operators -= and --
Multiple assignments
CODE SNIPPET
var foo = 3;
var bar = 2;
foo -= bar -= 1; // foo == 2; bar == 1;
CODE SNIPPET
var foo = "1";
var bar = "2";
foo -= bar -= " is a string";
// foo == NaN
// bar == NaN
138. Operators
operator | |
Assignment
CODE SNIPPET CODE SNIPPET
var foo = false; var foo = true;
var bar = function() {}; var bar = function() {};
var foobar = foo || bar; // foobar === bar var foobar = foo || bar; // foobar === true
foobar(); foobar(); // error
CODE SNIPPET
var foo = false;
var bar = false;
var barfoo = 5;
var foobar = foo || bar || barfoo;
// foobar === 5
139. Operators
operator &&
Assignment
CODE SNIPPET CODE SNIPPET
var foo = true; var foo = false;
var bar = function() {}; var bar = function() {};
var foobar = foo && bar; // foobar === bar var foobar = foo && bar; // foobar === false
foobar(); foobar(); // error
Inline conditions
CODE SNIPPET
var foo = true;
var bar = function() { alert("hello world!"); };
foo && bar(); // hello word!
140. Operators
operators && and | |
Good order makes a difference
CODE SNIPPET
var foo = true;
var bar = false;
var barfoo = false;
var foobar = foo && bar || barfoo || 5; // foobar === 5
141. Operators
Operator !
Negation Double negation (converts
to Boolean)
CODE SNIPPET CODE SNIPPET
var foo = 5; var foo = 5;
!foo; // false !!foo; // true
var foo = 0;
!foo; // true
var foo = "0";
!foo; // false
var foo = "1";
!foo; // false
142. Operators
operator ~
Bitwise operator
Numbers rounding
CODE SNIPPET
var foo = 5.743534;
~~foo; // 5
typeof ~~foo; // "number"
-(n + 1) when ―n‖ is an integer
CODE SNIPPET
var foo = -1;
~foo; // 0
143. Operators
comparison operators ( > , >= , <, <=, ==, ===, !=, !==)
Return value of Boolean type
Can be used as part of more complex expression
CODE SNIPPET
var a = 0,
b = 5,
c = a || b > a
alert(c); // "true"
144. Operators
String comparison
Strings are compared using alphabetical order
―Alphabetical order‖ is defined by the numerical order of the
16-bit Unicode values that make up the strings
CODE SNIPPET CODE SNIPPET
alert("b" > "a"); // "true" alert("cat" > "cats"); // "false"
145. Operators
Comparison of Different types
Values are converted to numbers except for the case
when both values are strings
CODE SNIPPET
alert("2" > 1); // "true"
alert("02" == 2); // "true"
alert(0 == false); // "true"
146. Operators
Strict Equality(===, !==)
Usual equality check can't distinguish the values that belong
to different types but have the same number representation
Strict equality operator is used to check equality without
type conversion
CODE SNIPPET
alert("02" === 2); // "false"
alert(0 === false); // "false"
147. Operators
Comparison with NULL and Undefined
null and undefined are not equal to 0 in comparisons
null and undefined are equal only to each other
When converted to a number
null is 0
undefined is NaN
CODE SNIPPET CODE SNIPPET
alert(null > 0); // "false" alert(undefined > 0); // "false"
alert(null == 0); // "false" alert(undefined < 0); // "false"
alert(null >= 0); // "true" alert(undefined == 0); // "false"
148. Operators
Object Conversion
toString and valueOf are methods for string and number
conversion respectively
String and number conversion can be overridden
If the operation requires a primitive value the object is
converted to the primitive first and then operation is
performed
Number conversion is used to convert object to primitive
(exception is built-in Date object)
149. alert(user); // [object Object]
Operators
string Conversion of objects
toString is declared in Object.prototype
toString can be overridden in user-defined object
toString should return any primitive value, otherwise it will
cause an error
CODE SNIPPET CODE SNIPPET
var user = { var user = {
firstName: "John" firstName: "John",
}; toString: function () {
return "user " + this.firstName
alert(user) // "[object Object]" }
};
alert(user) // "user John"
150. Operators
String conversion of objects
Built-in objects have their own implementation of toString
CODE SNIPPET
alert([1, 2]); // toString for Arrays – list of elements "1, 2"
alert(new Date()); // toString for Date – string representation of date
alert(function () {}); // toString for Function – source code of function
151. Operators
Number conversion of objects
valueOf is declared in Object.prototype but it returns object
itself and therefore is ignored
valueOf can be overridden in user-defined object
valueOf should return any primitive value, otherwise it will
be ignored
In case valueOf is ignored or not declared toString method
is used instead
152. Operators
Number conversion of objects
Most built-in objects don't have valueOf implementation
and therefore string and number conversion gives the same
results (exception is Date object which supports both string
and number conversion)
CODE SNIPPET
alert(new Date()); // toString - string representation of date
alert(+new Date()); // valueOf – number of milliseconds from 01.01.1970
153. Operators
Comparisons with objects
If both operands are objects operators (==, !=) check if
operands are or aren't references to the same object
In all other cases number conversion is used to get primitive
type and then perform operation (this is also true for
arithmetic operators)
CODE SNIPPET
var a = {},
b = {},
c = a;
alert(a == b); // "false"
alert(a == c); // "true"
154. Operators
Comparisons with objects
CODE SNIPPET CODE SNIPPET
var obj = { var a = {
valueOf: function () { valueOf: function () {
return 1; return 1;
} }
}; };
alert(obj == true); // "true" var b = {
alert(obj + "test"); // "1test" valueOf: function () {
return 2;
}
};
alert(b > a); // "true"
155. WHAT IS Javascript
JavaScript is a language that has
unique execution nuances
156. ENGINE RUNTIME
Execution Context
Abstract concept for differentiation of
executable code
Every time when control is transferred to executable
code, control enters an execution context.
Defined in ECMA-262
Consistent concept, but multiple implementations
157. Execution context
Types of executable code
There are 3 types of JavaScript code
Global code
Function code
Eval code
Every code is evaluated in its context
160. Execution context
Evalcode
Very special type of code
Executes in its own context but affects
calling context
In Strict Mode evaled code evaluates in its own sandbox
161. Execution context
Evalcode
Executable code EC stack
CODE SNIPPET CODE SNIPPET
ECStack = [
// influence global context globalContext
eval('var x = 10'); ];
// eval('var x = 10');
(function foo() { ECStack.push({
// and here, variable "y" is context: evalContext,
callingContext: globalContext
// created in the local context });
// of "foo" function
ECStack.pop(); // eval exited context
eval('var y = 20'); ECStack.push(<foo> functionContext); // foo function call
})();
// eval('var y = 20');
ECStack.push({
alert(x); // 10 context: evalContext,
callingContext: <foo> functionContext
alert(y); // "y" is not defined });
ECStack.pop(); // return from eval
ECStack.pop(); // return from foo
162. Execution context
LOGICAL layout
Execution
context
EC may be represented as
simple object
VARIABLE OBJECT
Scope chain
THIS VALUE
163. Execution context
Variable object
A Variable Object (VO) is tied to EC
Abstract store for
Variables (var, VariableDeclaration)
Function declarations (FunctionDeclaration, FD)
Function format parameters
164. Variable Object
Logical layout
Declaration Variable Object
CODE SNIPPET CODE SNIPPET
var a = 10; // Variable object of the global context
VO(globalContext) = {
function test(x) { a: 10,
var b = 20; test: <reference to function>
}; };
test(30); // Variable object of the "test" function
context
VO(test functionContext) = {
x: 30,
b: 20
};
165. Variable Object
types
Function context VO
GLOBAL context VO
(VO === AO, <arguments> object and
(vo===this===global)
<formal parameters> are added)
166. Variable Object
Global context vo
Allows indirect referencing through
window object
Lifetime tied to application
lifetime CODE SNIPPET
global = {
Singleton Math: <...>,
String: <...>
...
...
window: global
};
167. Variable Object
function context vo
Doesn`t allow indirect referencing
VO`s role plays Activation Object
An activation object is created on entering the context
of a function and initialized by property arguments
which value is the Arguments object
CODE SNIPPET
VO(functionContext) === AO;
168. Variable Object
Activation object
Arguments contains CODE SNIPPET
AO = {
callee - the reference to the current function arguments: <ArgO>
};
length - quantity of real passed arguments
properties-indexes
169. Variable Object
Activation object
CODE SNIPPET
function foo(x, y, z) {
alert(foo.length); // 3
Variable number of parameters alert(arguments.length); // 2
// reference of a function to itself
Runtime function inspection alert(arguments.callee === foo); // true
// parameters sharing
alert(x === arguments[0]); // true
alert(x); // 10
arguments[0] = 20;
alert(x); // 20
x = 30;
alert(arguments[0]); // 30
z = 40;
alert(arguments[2]); // undefined
arguments[2] = 50;
alert(z); // 40
}
foo(10, 20);
170. Execution context
Execution stages
Two stages of code handling
Entering the context where all the data are created
Formal parameter initialization
Function declaration
Variable declaration
The code execution stage
171. Execution context
Entering Execution context
For each formal parameter
Property of the VO with a name and value of
formal parameter is created
For not passed parameters — property of VO
with a name of formal parameter and value
undefined is created
172. Execution context
Entering Execution context
For each function declaration
A property of the variable object with a name and value
of a function-object is created
If the variable object already contains a property with
the same name, replace its value and attributes
173. Execution context
Entering Execution context
For each variable declaration
a property of the variable object with a variable name
and value undefined is created
if the variable name is already declared, declaration
does not disturb the existing property.
174. Execution context
Entering Execution context
Executable code Activation Object
CODE SNIPPET CODE SNIPPET
function test(a, b) { AO(test) = {
var c = 10; a: 10,
function d() { } b: undefined,
var e = function _e() { }; c: undefined,
(function x() { }); d: <reference to FunctionDeclaration "d">
} e: undefined,
arguments: <Args>
test(10); // call };
175. Execution context
Execution phase
Variables and function declarations are
hoisted, but not assignments
Original source Internal representation
CODE SNIPPET CODE SNIPPET
foo(); var bar;
function foo() { function foo() {
console.log(bar); alert(bar);
} }
var bar = 10; foo();
bar = 10;
176. Execution context
Function -level scoping
ES3 has no block-level scoping defined
Variable declared in a block visible everywhere in a
function
CODE SNIPPET
(function () {
{
var a = 10;
}
console.log(a); // 10
})();
177. Execution context
Function -level scoping
ES6 Harmony allows block-level scoping
with let keyword
CODE SNIPPET
(function () {
{
let a = 10;
}
console.log(a); // Reference error
})();
178. Execution context
LOGICAL layout
Execution
context
EC may be represented as
simple object
VARIABLE OBJECT
Scope CHAIN
THIS VALUE
179. Execution context
Scope chain
List of all (parent) variable objects for the
inner contexts
Created at function call
Consists of
Variable Object of currently executing code unit
Internal [[Scope]] field
180. Scope chain
Logical layout
CODE SNIPPET
Used for identifier lookup activeExecutionContext = {
VO: {...}, // or AO
Traversing scope chain this: thisValue,
Scope: [ // Scope chain
2D lookup with prototypes // list of all variable objects
// for identifiers lookup
]
}
CODE SNIPPET
Scope = AO + [[Scope]]
181. Scope chain
[[scope]] property
[[Scope]] is a chain of all parent VO, which are above
the current function context
[[Scope]] is saved to the function at its creation
Implements Lexical (Static) Scoping
182. Scope chain
scoping
Executable code Scope chain
CODE SNIPPET CODE SNIPPET
var x = 10; barContext.Scope = barContext.AO +
bar.[[Scope]] // i.e.:
function foo() {
var y = 20; barContext.Scope = [
barContext.AO,
function bar() { fooContext.AO,
var z = 30; globalContext.VO
alert(x + y + z); ];
}
bar();
}
foo(); // 60
183. Scope chain
closure
Closure is a functional concept
Consist of 2 parts
Function or function pointer
Referencing environment – a table of references to variables form
outer scope
184. Closure
example
CODE SNIPPET
Inner is a function var f = function outer() {
var a = 10;
Scope of outer function forms return function inner() {
referencing environment }
return a;
};
f1 = f();
console.log(f1()); // 10
186. Closure
nuances
incorrect Correct
CODE SNIPPET CODE SNIPPET
var array = [0, 1, 2]; var array = [0, 1, 2];
for (var i = 0; i < array.length; i++) { for (var i = 0; i < array.length; i++) {
array[i] = function () { (function (i) {
console.log(i); array[i] = function () {
}; console.log(i);
} };
})(i);
array[0](); // 3 }
array[0](); // 0
187. Closure
nuances
Watch out for context switches
CODE SNIPPET CODE SNIPPET
var person = { var person = {
firstName: 'Douglas', firstName: 'Douglas',
say: function () { say: function () {
function sayName() { var me = this;
console.log(this); // window or undefined
return this.firstName; function sayName() {
} return me.firstName;
}
return sayName(); return sayName();
} }
}; };
person.say(); person.say();
188. Execution context
LOGICAL layout
Execution
context
EC may be represented as
simple object
VARIABLE OBJECT
Scope chain
THIS VALUE
189. Execution context
This value
Special context object
Not tied to particular object
Can be set at runtime
Property of EC
Never participates in identifier lookup
Determined only once when entering EC
Immutable
190. This value
Global scope
Executable code
CODE SNIPPET
// explicit property definition of the global object
this.a = 10; // global.a = 10
alert(a); // 10
// implicit definition via assigning to unqualified identifier
b = 20;
alert(this.b); // 20
// also implicit via variable declaration because variable
object of the global context
// is the global object itself
var c = 30;
alert(this.c); // 30
191. This value
Call expression
CODE SNIPPET
Value of this is determined function foo() {
alert(this);
by the form of a call }
expression foo(); // global or undefined (strict mode)
alert(foo === foo.prototype.constructor); // true
// but with another form of the call expression
// of the same function, this value is different
foo.prototype.constructor(); // foo.prototype
192. This value
Call expression
Manual setting of ThisValue
Function.prototype.call
Function.prototype.apply
Function.prototype.bind
ThisValue as first parameter
193. This value
CALL
CODE SNIPPET
ThisValue as first parameter function a(c) {
alert(this.b);
Comma-separated list of }
alert(c);
parameters // this === {b: 20}, this.b == 20, c == 30
a.call({ b: 20 }, 30);
Executes a function
194. This value
apply
CODE SNIPPET
ThisValue as first parameter function a(c) {
alert(this.b);
Array of parameters }
alert(c);
Executes a function // this === {b: 30}, this.b == 30, c == 40
a.apply({ b: 30 }, [40])
195. This value
bind
CODE SNIPPET
ThisValue as first parameter function a(c) {
alert(this.b);
Comma-separated list of }
alert(c);
parameters // this === {b: 30}, this.b == 30, c == 40
(a.bind({ b: 30 }, 40))();
Returns a function
196. WHAT IS Javascript
JavaScript is a language that has
unique implementation of OOP
197. patterns & practices
modularity
Modules are building blocks of the app
Key properties
Loose coupling
High cohesion
Facilitate clean and flexible architecture
198. patterns & practices
modularity
Language has no built-in concept of modules
Modules are simulated using
Functions
Local variables
Closures
Dozen of design patterns available
203. modularity
Revealing Module pattern
CODE SNIPPET
Language features used var MY_APP_ONE = (function () {
// Private variables
var secret1 = 'Hello';
Self-calling functions var secret2 = 'World';
Closures // Private functions
var privateFoo = function () {};
var publicFoo = function () {};
var publicBar = function() {};
// Publicly exposed
return {
foo: publicFoo,
bar: publicBar
};
})();
204. modularity
Module revealing pattern
pros cons
Clean syntax Hard to extend
Private members Even harder to
Common syntax for accessing override
private and public members No way of dependency
management
205. modularity
AMD
Developed as standard for async module
loading
On demand async module loading
Built-in dependency management
Has corresponding specification
207. modularity
AMD
CODE SNIPPET
Language features used // shirt.js
define({
color: "black",
Self-calling functions size: "large"
});
Closures // logger.js
define(["shirt"], function (shirt) {
return {
logTheShirt: function () {
console.log(
"color: " + shirt.color +
", size: " + shirt.size
);
}
};
});
208. modularity
AMD
pros cons
Clean syntax Async nature may lead
Async loading to spaghetti code
Dependency management Requires build tool to
be used in minified file
210. modularity
Commonjsmodules 1.1
Concise API
require
module.exports
Modules referred to by name or path
One module one script file mapping
Can`t be used in minification scenarios
211. modularity
Commonjsmodules 1.1
CODE SNIPPET
Language features used // hello.js
exports.hello = function () {
return 'Hello World';
Closures };
//app.js
var example = require('./example.js');
example.hello();
212. modularity
Commonjsmodules 1.1
pros cons
Clean syntax Sync loading is inappropriate in
Dependency management Web browser
Doesn`t support minification
scenarios
213. patterns & practices
inheritance
No classical inheritance
Lots of ways to achieve inheritance
Pseudo-classical
Prototypal
Functional
Don’t try to pretend you`re programming on some
other language
215. Pseudo-classical pattern
Key ideas
Key ideas
The object is created by a constructor function
Properties are put into constructor function
Methods and default properties are put into prototype
216. Pseudo-classical pattern
Base class
CODE SNIPPET
Example
function Animal(name) {
canWalk property will be this.name = name
overridden in concrete instance }
Animal.prototype = {
Constructor assignment makes constructor: Animal,
instanceof operator work canWalk: true,
sit: function() {
this.canWalk = false
alert(this.name + ' sits down.')
}
}
var animal = new Animal('Pet') // (1)
217. Pseudo-classical pattern
Base class
Initially After sit
Animal.prototype Animal.prototype
{ {
canWalk: ‘true’, canWalk: ‘true’,
sit: function sit: function
} }
[[prototype]] [[prototype]]
instance instance
{
{
name: ‘Pet’,
name: ‘Pet’
canWalk: ‘false’
}
}
218. Pseudo-classical pattern
Inheritance function
Inherit base class prototype
and allow extensibility
CODE SNIPPET
function extend(Child, Parent) {
var F = function () { };
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.superclass = Parent.prototype;
}
219. Pseudo-classical pattern
Derived class
CODE SNIPPET
Example function Rabbit(name) {
Superclass constructor called to Rabbit.superclass.constructor.apply(this,
arguments);
initialize properties defined in }
base class extend(Rabbit, Animal);
Rabbit.prototype.jump = function () {
this.canWalk = true;
alert(this.name + ' is jumping.');
};
221. Pseudo-classical pattern
encapsulation
CODE SNIPPET
Convention based encapsulation
Animal.prototype.walk = function () {
Common practice is to prefix alert('walking');
};
protected members with _
Animal.prototype._run = function () {
alert('running');
}
222. Pseudo-classical pattern
statics
CODE SNIPPET
Static properties and functions function Animal() {
Assigned directly to the constructor Animal.count++
}
Animal.count = 0
new Animal()
new Animal()
alert(Animal.count); // 2
224. Prototypal
Key ideas
Key ideas
The object is created by special function
This function links object with prototype
Freedom of choice where to put properties and
methods
225. Prototypal
Object creation
Links empty object with ES5 has dedicated function
specified prototype
CODE SNIPPET CODE SNIPPET
function object(o) {
function F() { } Object.create(prototype, propertyDescriptors)
F.prototype = o;
return new F();
}
226. Prototypal
example
CODE SNIPPET
Derived object inherits var base = {
from base via prototype };
a: 1
var derived = object(base);
derived.print = function() {
console.log(this.a);
};
derived.print();
236. Performance optimization
Keep it simple
Simpler - faster
Slow
CODE SNIPPET
var min = Math.min(a, b);
arr.push(val);
Fast
CODE SNIPPET
var min = a < b ? a : b;
arr[arr.length] = val;
237. Special thanks
Reviewers & inspirations
Damian Wielgosik
His amazing depth knowledge of JS inspired my presentation.
Check out his Just Advanced JavaScript on SlideShare.
Pavel Hizhuk
His amazing understanding of type casting and comparisons
reflected directly in this presentation.
238. Special thanks
Reviewers & inspirations
My Girlfriend
For constant support and patience in listening my crazy saying
about how badly something implemented, for sleepless nights
and funny jokes :)