just advanced javascript
DESCRIPTION
Over 200 helpful slides about advanced JavaScript.TRANSCRIPT
Just Advanced JavaScriptJust Advanced JavaScript
Damian Wielgosikhttp://varjs.comhttp://varjs.comhttp://ferrante.pl
Damian Wielgosikvarjs.comvarjs.com
http://ferrante.pl
ECMA StandardECMA StandardECMA StandardECMA Standard
http://www.ecmainternational.org/publications/files/ECMApublications/files/ECMAECMA-262.pdf
http://www.ecma-international.org/publications/files/ECMA-ST/publications/files/ECMA-ST/
ECMA Standard• What is ECMA?• ECMAScript and JavaScript• history• ECMA 262• ECMA 262• future
– desktop– server-side– iPhone WebKit, Nokia WRT – Nintendo Wii– OLPC (One laptop per child)– ...
0.1 + 0.2 !== 0.30.1 + 0.2 !== 0.3ECMA bad parts
0.1 + 0.2 !== 0.30.1 + 0.2 !== 0.3ECMA bad parts
JScriptJScriptJScriptJScript
JScript• Debug• Enumerator• VBArray• ActiveXObject• ActiveXObject• GetObject()• @cc_on• (new Data).getVarDate()• host objects
JavaScript 1.5JavaScript 1.5JavaScript 1.5JavaScript 1.5
JavaScript 2.0JavaScript 2.0JavaScript 2.0JavaScript 2.0
BrowsersBrowsersBrowsersBrowsers
JavaScript JavaScript JavaScript – go!JavaScript – go!
JavaScript – go!• attaching scripts to your site
1. <script type="text/javascript">2. var win = window;3. //...
1. <script type="text/javascript" src="script.js"></script>
3. //...4. </script>
• charset
• version
1. <script type="text/javascript" src="
1. <script type="application/javascript;version=1.8" src="script.js" charset="utf-8">
attaching scripts to your site<script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="script.js" charset="utf-8">
<script type="application/javascript;version=1.8" 8">
Asynchronous LoadingAsynchronous LoadingAsynchronous LoadingAsynchronous Loading
Asynchronous Loading• why Asynchronous Loading?• basic usage:1. var script = document.createElement("script");2. script.type = "text/javascript";3. script.src = "someScript.js";
• or just put <script></script> before </body>
3. script.src = "someScript.js";4. document.body.appendChild(script);
why Asynchronous Loading?
var script = document.createElement("script");
or just put <script></script> before </body>document.body.appendChild(script);
Lazy LoadingLazy LoadingLazy LoadingLazy Loading
Lazy Loading• why Lazy Loading?
– the code available only on request– less unnecessary HTTP traffic– the control over JS code
• basic usage (by one of many LazyLoading libraries):• basic usage (by one of many LazyLoading libraries):1. LazyLoad.load('http://example.com/foo.js',2. LazyLoad.load('http://example.com/bar.js', loadComplete, this,
true);
the code available only on requestless unnecessary HTTP traffic
basic usage (by one of many LazyLoading libraries):basic usage (by one of many LazyLoading libraries):LazyLoad.load('http://example.com/foo.js', loadComplete);LazyLoad.load('http://example.com/bar.js', loadComplete, this,
Code compressionCode compressionCode compressionCode compression
Code compression• why to compress JavaScript code?
– less HTTP traffic– faster load time
• code minification– Dean Edwards packer– Dean Edwards packer
• http://dean.edwards.name/packer– Google kit
• http://code.google.com/closure/compiler– YUI Compressor
• http://developer.yahoo.com/yui/compressor• GZIP• obfuscation
why to compress JavaScript code?
dean.edwards.name/packer
://code.google.com/closure/compiler
developer.yahoo.com/yui/compressor
Advanced basicsAdvanced basicsAdvanced basicsAdvanced basics
Advanced basics• how we used to write JavaScript code
bad parts• variables and types• operators• functions• arrays• statements• falsy values• == vs ===• bitwise operators
how we used to write JavaScript code – good and
How we used to write How we used to write JavaScript code
bad parts
How we used to write How we used to write JavaScript code – good and
bad parts
Writing JavaScript code –
What can you say about your JavaScript code? Do you like this language? What does just annoy you?
Exercise
good and bad parts
What can you say about your JavaScript code? Do you like this language?
Writing JavaScript code –1. window.onload = function() {2. function show() {3. var article = document.getElementById("id");4. article.style.display = "block";5. }6. function hide () {7. var article = document.getElementById("id");8. article.style.display = "none";9. }10.};
good and bad parts
var article = document.getElementById("id");article.style.display = "block";
var article = document.getElementById("id");article.style.display = "none";
Writing JavaScript – good and bad parts1. function show() {2. var article = document.getElementById("id");3. article.style.display = "block";4. //...5. someVar = "oh yeah";6. }6. }7. function hide () {8. var article = document.getElementById("id");9. article.style.display = "none";10.}11.12.window.onload = function() {13. document.getElementById("niceId").onclick = show;14. document.getElementById("notThatNiceId").onclick = hide;15.};
good and bad parts
var article = document.getElementById("id");article.style.display = "block";
var article = document.getElementById("id");article.style.display = "none";
document.getElementById("niceId").onclick = show;document.getElementById("notThatNiceId").onclick = hide;
Writing JavaScript – good and bad parts1. <body onload="document.getElementById('foobar').2. onclick = function() { alert('Yes, you can!'); }"></body>
1. <body onload="Load()"></body>
1. <a onclick="this.style.display = 'none'; return false;"></a>
1. var foobar = "bar"2. bar = "foo";3. var obj = new Object("");4. var string = new String("Foobar");5. var array = new Array(1, 2, 3);6. var img = new Image();
good and bad parts<body onload="document.getElementById('foobar').onclick = function() { alert('Yes, you can!'); }"></body>
<a onclick="this.style.display = 'none'; return false;"></a>
var string = new String("Foobar");
Good parts Good parts a blessing in disguise?
Good parts -Good parts -a blessing in disguise?
Writing JavaScript code –• JavaScript and Java• dig into AJAX
– AJAX is available since IE 5 (!)• lots of stuff to explore, sleeping power• JavaScript just makes it fun• are we sure we have been writing JS?
good and bad parts
lots of stuff to explore, sleeping powerJavaScript just makes it funare we sure we have been writing JS?
Writing JavaScript code –
Try to shorten the numbers declarations
Exercise
1. var n = 124500000;2. var n2 = 0.00005;
good and bad parts
Try to shorten the numbers declarations
Writing JavaScript code –
Try to shorten the numbers declarations
Exercise - solution
1. var n = 1245e5;2. var n2 = 5e-5;
good and bad parts
Try to shorten the numbers declarations
JavaScript – where hacking JavaScript – where hacking begins!
where hacking where hacking begins!
Variables and typesVariables and typesVariables and typesVariables and types
Variables• var is your friend1. var barfoo; // undefined, is a default value of every variable2. var foobar = "string";3. var foobar = -5; // dynamic typing, no type control4. var foo = function() { return 5; }; 5. var bar = 2e3; // 20005. var bar = 2e3; // 20006. var barbar = Number.Infinity;7. var foofoo = null;8. var dec = .3; // the other way to write float numbers9. var hex = 0xF; // 15 written in hex10.var t = new Date().getTime(); // UNIX timestamp e.g. 1262184428510
• declaring many variables at one time1. var foobar = "string", 2. foo = function() {},3. bar = 2e3;
// undefined, is a default value of every variable
// dynamic typing, no type controlvar foo = function() { return 5; }; // function as variables
// the other way to write float numbers// 15 written in hex
// UNIX timestamp e.g. 1262184428510
declaring many variables at one time
typeoftypeoftypeoftypeof
Variable types• string
• number
1. var foobar = "variable types";2. typeof foobar; // "string"
• number
• boolean
1. var foobar = 0.5;2. typeof foobar; // "number"3. var foobar = 1;4. typeof foobar; // "number"
1. var foobar = true;2. typeof foobar; // "boolean"
Variable types• function
• object
1. var foobar = function() {};2. typeof foobar; // "function"
• object
• undefined
1. var foobar = {};2. typeof foobar; // "object"
1. var foobar;2. typeof foobar; // "undefined"
What about What about What about null?What about null?
typeof null == "object"typeof null == "object"1. var foobar = null;2. typeof foobar; // "object"
typeof null == "object"typeof null == "object"
NaNNaNNaNNaN
NaN• paradoxical type
• watch out, easy to overwrite!
1. var foobar = NaN;2. typeof foobar; // "number"
• watch out, easy to overwrite!
• getting NaN
1. var NaN = "string";2. typeof NaN; // "string"
1. var foobar = "string" * 2, bar = "string" / 2;2. var foo = +"string", barfoo = +[1, 2, 3], foobar2 = undefined
watch out, easy to overwrite!watch out, easy to overwrite!
var foobar = "string" * 2, bar = "string" / 2;var foo = +"string", barfoo = +[1, 2, 3], foobar2 = undefined – 2;
OperatorsOperatorsOperatorsOperators
Assigment operator "="• "="
– multiple assigments1. var foobar = 1;2. var foo = 2;3. var bar = foo = foobar = 3; // bar == 3, foo == 3, foobar == 3
– assignment order is from right to left3. var bar = foo = foobar = 3; // bar == 3, foo == 3, foobar == 3// bar == 3, foo == 3, foobar == 3
assignment order is from right to left// bar == 3, foo == 3, foobar == 3
"+" operator• string concatenation
• casting to number ("number" type)1. var foobar = "This " + "is " + "a variable.";
1. var foobar = +true; // 12. var foobar = +false; // 0
• adding
• string priority
2. var foobar = +false; // 0
1. var foobar = 5 + 1; // 6
1. var foobar = "1" + 0; // 10 !2. typeof foobar; // "string"3. var foobar = 0 + "1"; // 014. typeof foobar; // "string"
casting to number ("number" type)var foobar = "This " + "is " + "a variable.";
toString() == "" +toString() == "" +1. var foobar = function() {};2. var foobar2string = "" + foobar; 3. typeof foobar2string; // "string"
toString() == "" +toString() == "" +var foobar2string = "" + foobar; // "function() {}"
// "string"
(new Date).getTime() == (new Date).getTime() == +new Date
(new Date).getTime() == (new Date).getTime() == +new Date
Operators "+=" and "++"• forget about var
• casting to string
1. var foobar = 1;2. foobar += 1; // 2
• casting to string
• += !== ++
1. var foobar = "1";2. foobar += 5; // "15" !
1. var foobar = "5";2. foobar++;3. typeof foobar; // "number"
Operators "+=" and "++"
Operators "+=" and "++"• multiple assigments1. var foo = 1;2. var bar = 2;3. foo += bar += 3; // foo == 6; bar == 5;
1. var foo = "1";2. var bar = "2";3. foo += bar += " is a string";4. // foo == "12 is a string; 5. // bar == "2 is a string";
Operators "+=" and "++"
// foo == 6; bar == 5;
Operators "-=" and "--"• forget about var
• -= does not behave like +=
1. var foobar = 1;2. foobar -= 1; // 0
• -= does not behave like +=
• // number1. var foobar = "1";2. foobar -= 5; // -4 (number) !
1. var foobar = "5";2. foobar--;3. // 44. typeof foobar; // "number"
= does not behave like +== does not behave like +=
Operators "-=" and "--"• multiple assigments1. var foo = 3;2. var bar = 2;3. foo -= bar -= 1; // foo == 2; bar == 1;
1. var foo = "1";2. var bar = "2";3. foo -= bar -= " is a string";4. // foo == NaN5. // bar == NaN
// foo == 2; bar == 1;
"||" operator• assigment1. var foo = false;2. var bar = function() {};3. var foobar = foo || bar; // foobar === bar4. foobar();
1. var foo = true;2. var bar = function() {};3. var foobar = foo || bar; // foobar === true4. foobar(); // error
1. var foo = false;2. var bar = false;3. var barfoo = 5;4. var foobar = foo || bar || barfoo;
// foobar === bar
// foobar === true
var foobar = foo || bar || barfoo; // foobar === 5
"&&" operator• assigment1. var foo = true;2. var bar = function() {};3. var foobar = foo && bar; // foobar === bar4. foobar();
• inline conditions
1. var foo = false;2. var bar = function() {};3. var foobar = foo && bar; // foobar === false4. foobar(); // error
1. var foo = true;2. var bar = function() { alert("hello world!"); };3. foo && bar(); // hello word!
// foobar === bar
// foobar === false
var bar = function() { alert("hello world!"); };
Operators "&&" and "||"• good order makes a difference1. var foo = true;2. var bar = false;3. var barfoo = false;4. var foobar = foo && bar || barfoo || 5;
good order makes a difference
var foobar = foo && bar || barfoo || 5; // foobar === 5 !
"!" as a negation operator• converts to bool1. var foo = 5;2. !foo; // false3. var foo = 0;4. !foo; // true
• double negation
4. !foo; // true5. var foo = "0";6. !foo; // false7. var foo = "1";8. !foo; // false
1. var foo = 5;2. !!foo; // true
"!" as a negation operator
The power of "~"• bitwise operator• numbers rounding1. var foo = 5.743534;2. ~~foo; // 53. typeof ~~foo; // "number" !
• - (n + 1) when "n" is an integer3. typeof ~~foo; // "number" !
1. var foo = -1;2. ~foo; // 0
1. var default = -1;2. if (!~default) { }; // if default remains
(n + 1) when "n" is an integer
// if default remains -1
ArraysArraysArraysArrays
Arrays• declaration1. var foo = [];2. foo.length; // 03. typeof foo; // "object" !
1. var foo = [, , ,];
• forget about new Array
1. var foo = [, , ,];2. foo.length; // 4 (IE) or 3 (Firefox)3. typeof foo[2]; // "undefined"4. [1, function() {}, null].length // 3
1. var foo = new Array([2, 3, 4].length);2. foo.length; // 33. typeof foo[2]; // "undefined"4. var Array = 100;5. var foo = new Array([2, 3, 4].length);
// 4 (IE) or 3 (Firefox)
// 3
var foo = new Array([2, 3, 4].length);
var foo = new Array([2, 3, 4].length); // error
Arrays• forget about new Array1. var foo = [];2. var len = 5;3.4. foo[len-1] = undefined;5. foo.length; // 55. foo.length; // 56. typeof foo[2] // "undefined"
Arrays
What is the result of following code:
var x = [typeof 5, typeof null][1]; typeof typeof x; // ?
Exercise
][1];
Arrays
What is the result of following code:
var x = [typeof 5, typeof null][1]; typeof typeof x; // "string"
Exercise - solution
][1];
FunctionsFunctionsFunctionsFunctions
Functions• declaration1. var foo = function() { return 5; };2. foo(); // 5
1. function foo() { return 5; };2. foo(); // 5
• anonymous functions as arguments
2. foo(); // 5
1. var foo = function foo() { return 5; };2. foo(); // 5
1. var f = function() { alert("hello world!"); };2. var foobar = function(fn) {3. fn();4. }5. foobar(f); // hello world!
var foo = function() { return 5; };
anonymous functions as arguments
var foo = function foo() { return 5; };
var f = function() { alert("hello world!"); };
Functions• one function can return another function1. var foo = function() { return function() {}; };2. foo(); // function() {};
one function can return another functionvar foo = function() { return function() {}; };
Function declarations matterFunction declarations matterFunction declarations matterFunction declarations matter
http://yura.thinkweb2.com/namedhttp://yura.thinkweb2.com/named-function-expressions
http://yura.thinkweb2.com/namedhttp://yura.thinkweb2.com/namedexpressions
Functions
What is the result of fn()?var i = 5;var fn = function() {
return i++; };
Exercise #1
return i++; };fn(); // ?
What is the result of typeof fn()?var fn = function() {};typeof fn(); // ?
Exercise #2
Functions
What is the result of fn()?var i = 5;var fn = function() {
return i++; };
Exercise #1 - solution
return i++; };fn(); // 5
What is the result of typeof fn()?
var fn = function() {};typeof fn(); // "undefined"
Exercise #2 - solution
StatementsStatementsStatementsStatements
Conditional statements• if conditional statements without the braces1. if (true)2. fn();
1. if (true)2. fn();
• inline conditions
2. fn();3. else4. fn2();5. fn3(); // out of statement !
1. var foo = true, bar = false;2. foo && fn();3. var foo = false, bar = true;4. foo && fn() || bar && fn2();
without the braces
Conditional statements• ternaly operator1. var fn = function() { return false; };2. var val = fn() ? "true" : "false";3. val; // "false"
var fn = function() { return false; };var val = fn() ? "true" : "false";
Loops• for loop without the braces
• a few words about good practices
1. var dt = [1, 2, 3];2. for (var i = 0, k = dt.length; i < k; j = dt[i] * 2, dt[i++] = j);
• a few words about good practices• while loop without the braces1. while(i--)2. j -= i;
1. while(i--)2. j -= i;3. j *= 2; // out of the loop!
loop without the braces
a few words about good practices
for (var i = 0, k = dt.length; i < k; j = dt[i] * 2, dt[i++] = j);
a few words about good practicesloop without the braces
!
Falsy valuesFalsy valuesFalsy valuesFalsy values
Falsy values• what are falsy values?• falsy values:
– null– undefined– 0– 0– NaN– ""– false
Falsy values• examples1. var falsyValue = 0;2. if (!falsyValue) {3. alert("falsy value!");4. }4. }5. var falsyValue = "";6. if (!falsyValue) {7. alert("falsy value!");8. }9. var falsyValue = NaN;10.if (!falsyValue) {11. alert("falsy value!");12.}13.// etc...
Falsy values• risks1. var falsyValue = "";2. if (falsyValue == 0) {3. alert("falsy value!");4. }4. }5. var falsyValue;6. if (falsyValue == null) {7. alert("falsy value!");8. }9. // etc...
== versus ===== versus ===== versus ===== versus ===
== versus ===
What are the results of following comparisonsvar foo = null;var bar;
Exercise
foo == bar; // ?10 == "10"; // ?"1e1" == 10; // ?"" === new String(""); // ?0 == null // ?
What are the results of following comparisons
== versus ===
What are the results of following comparisons?var foo = null;var bar;
Exercise - solution
foo == bar; // true10 == "10"; // true"1e1" == 10; // true"" === new String(""); // false0 == null // false
What are the results of following comparisons?
== versus ===• avoid ==
– unexpectable behaviour
– ECMA spec page 80.– possible usage:
1. ' \t\r\n ' == 0 // true
– possible usage:• typeof
• === is an effective solution– checks and compares the value and the type of variable
1. if (typeof fn == "function") {
1. if (typeof string == "string") {
=== is an effective solutionchecks and compares the value and the type of variable
if (typeof fn == "function") { // ... }
if (typeof string == "string") { // ... }
== versus ===• examples ===1. var falsyValue = "";2. if (falsyValue === 0) { // is never true3. // ...4. }4. }5. var falsyValue = false;6. if (falsyValue === "") { // is never true7. alert("falsy value!");8. }9. // etc...
// is never true
// is never true
Hands on bitwise operatorsHands on bitwise operatorsHands on bitwise operatorsHands on bitwise operators
Garbage collectorGarbage collectorGarbage collectorGarbage collector
Object model in JavaScriptObject model in JavaScriptObject model in JavaScriptObject model in JavaScript
Objects in JavaScript• what is an object in JavaScript?• primitives are not the real objects
– undefined– strings– numbers– numbers– null– false, true
• custom object model in JS
what is an object in JavaScript?primitives are not the real objects
Object literalsObject literalsObject literalsObject literals
Object literals• basics1. var obj = {2. property: "foobar",3. method: function() {}4. };
• an empty object
• arrays as objects
4. };5. typeof obj; // "object"6. obj.property; // "foobar"7. obj.method();
1. var obj = {};
1. var arr = [];2. typeof arr; // "object"
Object literals• objects can be returned by a function1. var fn = function() {2. return {3. property: "foobar",4. method: function() {}
• two ways to access the object's property
4. method: function() {}5. };6. };7. typeof fn(); // object8. fn().property; // "foobar"9. fn().method();
1. obj['property'];2. obj.property;
objects can be returned by a function
method: function() {}
two ways to access the object's property
method: function() {}
Functions as constructorsFunctions as constructorsFunctions as constructorsFunctions as constructors
Functions as constructors• basics1. var fn = function() {2. this.property = "foobar";3. this.method = function() {};4. };4. };5.6. var obj = new fn;7. typeof obj; // "object" !8. obj.property; // "foobar"9. obj.method(); // undefined
Functions as constructors
Functions as constructors• inline object initialization1. var fn = function() {2. this.property = "foobar";3. this.method = function() {4. return this.property;5. };5. };6. };7.8. typeof new fn; // object !9. (new fn).property; // "foobar"10.(new fn).method(); // "foobar"
Functions as constructors
return this.property;
.constructor.constructor.constructor.constructor
.constructor• .constructor property1. var obj = {2. property: "foobar",3. method: function() {}4. };4. };5.6. var fn = function() {7. this.property = "foobar";8. this.method = function() {};9. };10.11.obj.constructor // function Object() { [native code] }12.(new fn).constructor // fn...
// function Object() { [native code] }
.constructor• .constructor property1. var fn = function fn() {2. this.property = "foobar";3. this.method = function() {};4. };4. };5. (new fn).constructor // function fn() { ... }// function fn() { ... }
http://joost.zeekat.nl/constructorshttp://joost.zeekat.nl/constructors-considered
confusing.html
joost.zeekat.nl/constructorsjoost.zeekat.nl/constructorsconsidered-mildly-
confusing.html
.prototype.prototype.prototype.prototype
.prototype• what is .prototype?
– .prototype as an object
– .prototype as a starting point for object creation
1. var fn = function() { };2. typeof fn.prototype; // "object"
– .prototype as a starting point for object creation– prototype chaining
• Object.prototype• .prototype in constructors
as a starting point for object creationas a starting point for object creation
.prototype in constructors
1. var fn = function() { this.property = "bar"; };
1. var fn = function() { };2. fn.prototype = { property: "foobar" };3.4. var obj = new fn;5. obj.property // "foobar"
1. var fn = function() { };2. fn.prototype.property = function() { alert("hello world!"); };3.4. var obj = new fn;5. obj.property() // "hello world!"
1. var fn = function() { this.property = "bar"; };2. fn.prototype = { property: "foobar" };3.4. var obj = new fn;5. obj.property // "bar"
.prototype in constructors
var fn = function() { this.property = "bar"; };
fn.prototype = { property: "foobar" };
fn.prototype.property = function() { alert("hello world!"); };
var fn = function() { this.property = "bar"; };fn.prototype = { property: "foobar" };
.prototype in constructors
1. var fn = function() { };2. fn.prototype = { property: "foobar" };3. var obj = new fn;4.
• overwritting .prototype property and possible risks
4.5. fn.prototype = { property: "hello world!" };6. var obj2 = new fn;7. obj.property; // "foobar"8. obj2.property; // "hello world!"
• remember, .property always holds the reference to the object
.prototype in constructors
fn.prototype = { property: "foobar" };
property and possible risks
fn.prototype = { property: "hello world!" };
always holds the reference to
.prototype in constructors
1. var fn = function() { };2. fn.prototype.foo = "bar";3.4. var obj = new fn;
• updating the .prototype properties
4. var obj = new fn;5.6. fn.prototype.foo = "foo";7. obj.foo; // "foo" !
.prototype in constructors
properties
.prototype in constructors
1. var fn = function() {2. this.hello = "hello world!";3. };
• accessing object properties
4. fn.prototype = { 5. say: function() { alert(this.hello); } 6. };7.8. var obj = new fn;9. obj.say(); // "hello world!"
.prototype in constructors
accessing object properties
say: function() { alert(this.hello); }
.prototype in constructors
1. var fn = function() {2. this.hello = "hello world!";3. };
• impact on other object properties
4. fn.prototype = { 5. say: function() { alert(this.hello); },6. done: function() { this.hello = "hi!"; },7. hello: "witaj!"8. };9.10.var obj = new fn;11.obj.done();12.obj.say(); // "hi!"
.prototype in constructors
impact on other object properties
say: function() { alert(this.hello); },done: function() { this.hello = "hi!"; },
.prototype in constructors
What is the result of typeof obj.foobar?
Exercise
1. var fn = function() { 2. this.foobar = [];2. this.foobar = [];3. };4.5. fn.prototype = { foobar: "foobar" };6.7. var obj = new fn;8. typeof obj.foobar; // ?
.prototype in constructors
?
fn.prototype = { foobar: "foobar" };
.prototype in constructors
What is the result of typeof obj.foobar?
Exercise - solution
1. var fn = function() { 2. this.foobar = [];2. this.foobar = [];3. };4.5. fn.prototype = { foobar: "foobar" };6.7. var obj = new fn;8. typeof obj.foobar; // "object"
.prototype in constructors
?
fn.prototype = { foobar: "foobar" };
Inspecting objectsInspecting objectsInspecting objectsInspecting objects
Inspecting objects• for in1. var obj = {2. property: "foobar",3. method: function() {}4. };5. for (var i in obj) {
• hasOwnProperty
5. for (var i in obj) {6. alert("The value of key " + i +" is " + obj[i]);7. }
1. for (var i in obj) {2. if (obj.hasOwnProperty(i)) {3. alert("The value of key " + i +" is " + obj[i]);4. }5. }
alert("The value of key " + i +" is " + obj[i]);
alert("The value of key " + i +" is " + obj[i]);
Inspecting objects• __count__ (newst Firefox)1. var obj = {2. property: "foobar",3. method: function() {}4. };5. obj.__count__; // 2
• __proto__ (newest Firefox, Safari, Chrome, Opera)
5. obj.__count__; // 2
1. var fn = function() {};2. fn.prototype = { property: 2 };3. var obj = new fn;4. obj.__proto__; // { property: 2 }
__proto__ (newest Firefox, Safari, Chrome, Opera)
// { property: 2 }
Inspecting objects
1. var obj = {2. "5": "the key of mine is five"3. };4. obj.5; // error
1. var obj = {2. 5piec: "the key of mine is five" 3. };
1. var obj = {2. "5": "the key of mine is five"3. };4. obj['5']; // "the key of mine is five5. obj[5]; // "the key of mine is five
"5": "the key of mine is five"
5piec: "the key of mine is five" // error
"5": "the key of mine is five"
the key of mine is five"the key of mine is five"
toString()toString()toString()toString()
toString()1. var obj = {};2. obj.toString(); // "[object Object]"3.4. var fn = function() {};5. fn.toString(); // "function () { }"6.6.7. var number = 5;8. number.toString(); // "5"9.10.var fn = function() {};11.fn.prototype.toString(); // "[object Object]"12.13.var arr = [1, function() {}, 3];14.arr.toString(); // "1,function () {},3"
// "[object Object]"
// "function () { }"
// "[object Object]"
// "1,function () {},3"
What if I overwrite What if I overwrite What if I overwrite toString?What if I overwrite toString?
toString()1. var obj = {2. toString: function() {3. alert("Pff, forget about native toString"); 4. }5. };6.6.7. for (var i in obj) {8. alert(i); // IE6+?9. }
alert("Pff, forget about native toString");
instanceofinstanceofinstanceofinstanceof
instanceof• what instanceof does1. var fn = function() {};2. var obj = new fn;3.4. obj instanceof fn // true
• take care1. var fn = function foobar() {};2. var obj = new fn;3.4. obj instanceof foobar // error
instanceof• instanceof Array is not the best way to do array
detection1. var arr = []; 2. arr instanceof Array // true
1. var Array = function() {};2. var arr = []; 3. arr instanceof Array // false
is not the best way to do array
Array detection?Array detection?Array detection?Array detection?
Object.prototype.toStringObject.prototype.toString.call([]) === "[object Array]"Object.prototype.toStringObject.prototype.toString
.call([]) === "[object Array]"
instanceof
What is the result of following code?
Exercise
1. function foo() { return foo; }1. function foo() { return foo; }2. new foo() instanceof foo; // ?
instanceof
What is the result of following code?
Exercise - solution
1. function foo() { return foo; }1. function foo() { return foo; }2. new foo() instanceof foo; // false// false
deletedeletedeletedelete
delete• delete deletes, in general...1. var obj = {2. foo: "bar",3. bar: "foo"4. };5. typeof obj.foo; // "string"
• do not delete array elements!
5. typeof obj.foo; // "string"6. delete obj.foo;7. typeof obj.foo; // "undefined"
1. var arr = [1, 2, 3];2. delete arr[1];3. arr.length; // 3;4. arr.toString(); // 1,undefined,3
deletes, in general...
do not delete array elements!
delete• delete returns boolean1. var obj = {2. foo: "bar",3. bar: "foo"4. };5.5.6. delete obj.foo; // true7. delete obj.foobar; // false8. delete obj['bar']; // true
delete
What does this function return?
Exercise
1. (function(i){1. (function(i){2. delete i; 3. return i; // ?4. })(10);
delete
What does this function return?
Exercise - solution
1. (function(i){1. (function(i){2. delete i; 3. return i; // 104. })(10);
http://perfectionkills.com/http://perfectionkills.com/understanding
perfectionkills.com/perfectionkills.com/understanding-delete
Native constructorsNative constructors(built
Native constructorsNative constructors(built-in)
Native constructors• Object• Array• Function• Number• Number• String• RegExp• Boolean
Native constructors• Object.prototype1. Object.prototype.say = function() { alert("hello world!"); };2.3. var obj = {};4. obj.say(); // "hello world!"5.
• Array.prototype
5.6. var arr = [];7. arr.say(); // "hello world!"
1. Array.prototype.polishLength = function() {2. return "The array length is " + this.length;3. };4. var arr = [1, 2, 3];5. arr.polishLength(); // "The array length is
Object.prototype.say = function() { alert("hello world!"); };
Array.prototype.polishLength = function() {return "The array length is " + this.length;
// "The array length is 3"
Native constructors• Function.prototype1. Function.prototype.say = function() { alert("hello world!"); };2.3. var fn = function() {};4. fn.say(); // "hello world!"
• itd...
Function.prototype.say = function() { alert("hello world!"); };
Native constructors
Try to implement isEven function which works like following: (5).isEven() false
Exercise #1
Try to implement normalizeSpaces, which works like following: "Can I haz an hamburger?".normalizeSpaces() -> Can I haz an hamburger?.
Exercise #2
function which works like following: (5).isEven() ->
Try to implement normalizeSpaces, which works like following: "Can I haz an hamburger?".normalizeSpaces()
Native constructors
Try to implement isEven function which works like following: (5).isEven()
Exercise #1 - solution
1. Number.prototype.isEven = function() {1. Number.prototype.isEven = function() {2. return !(this % 2);3. }
function which works like following: (5).isEven() -> false
Number.prototype.isEven = function() {Number.prototype.isEven = function() {
Native constructors
Try to implement normalizeSpaces, which works like following: "Can I haz an hamburger?".normalizeSpaces() -> Can I haz an hamburger?.
Exercise #2 - solution
1. String.prototype.normalizeSpaces 2. return this.replace(/\s+/g, " ");3. };
Try to implement normalizeSpaces, which works like following: "Can I haz an hamburger?".normalizeSpaces()
normalizeSpaces = function() { s+/g, " ");
Native constructors• take care – could be overwritten!1. var Object = 5;2. Object.prototype.say = function() { alert("hello world!"); };3. // error4. var obj = {};5. obj.say();5. obj.say();
1. var Array = function() {};2. Array.prototype.say = function() { alert("hello world!"); };3.4. var obj = [];5. obj.say(); // error
could be overwritten!
Object.prototype.say = function() { alert("hello world!"); };
Array.prototype.say = function() { alert("hello world!"); };
ScopeScopeScopeScope
Scope• what is "scope"?• blocks range – is there something like that?1. {2. var i = 10;3. };3. };4. i; // 10
1. for (var i = 0; i < 10; i++) {2. };3.4. i; // 10
1. var i = 0;2. for (; i < 10; i++) {};
is there something like that?
Scope• function scope1. var fn = function() {2. var i = 10;3. };4.5. fn();5. fn();6. typeof i; // "undefined"
1. var fn = function() {2. i = 10;3. };4.5. fn();6. i; // 10
Scope• important curiosities1. var i = 10;2. var fn = function() {3. alert(i); // undefined !4. var i = 100;5. alert(i); // 100
• JavaScript engine scans for "var" declarations and sets the undefined values
5. alert(i); // 1006. }7.8. fn();
JavaScript engine scans for "var" declarations and
Scope• important curiosities1. var fn = function() {2. var i = 10;3. var foo = function() {4. if (i === 10) {5. var i = 20;5. var i = 20;6. }7. alert(i); // undefined8. };9. foo();10.}11.fn();
// undefined
Scope• important curiosities1. var arr = [1, 2, 3];2.3. var i = 0;4. for (var l = arr.length; i < l; i++) {5. arr[i] = function() {5. arr[i] = function() {6. alert(i);7. };8. }9.10.arr[0](); // 3 !
for (var l = arr.length; i < l; i++) {
How it really works?How it really works?How it really works?How it really works?
Scope
What is a value of "x" variable?
Exercise
1. var y = 1, x = y = typeof x;2. x; // ?2. x; // ?
Scope
What is a value of "x" variable?
Exercise - solution
1. var y = 1, x = y = typeof x;2. x; // "undefined"2. x; // "undefined"
ClosuresClosuresClosuresClosures
Closures1. var arr = [1, 2, 3];2.3. var i = 0;4. for (var l = arr.length; i < l; i++) {5. arr[i] = (function(i) {6. return function() {6. return function() {7. alert(i);8. }9. })(arr[i]);10.}11.12.arr[0](); // 1 !
for (var l = arr.length; i < l; i++) {
Closures• self-invoking functions1. (function() {2. alert("hello world");3. })();
• can take the arguments
• your own space
1. (function(y, z) {2. alert(y + z); // 3003. })(100, 200);
Closures• access to the out-of-scope variables defined in
outside1. var fn = function() {2. var i = 100;3.3.4. var foobar = function() {5. alert(i); // 1006. i = 300;7. };8.9. foobar();10. alert(i); // 30011.};
scope variables defined in
Closures1. var i = 100;2.3. var fn = function(x) {4. return x * i;5. };6.6.7. i = 20;8. fn(2); // 40
thisthisthisthis
this• this, which is hard to define• this as a context1. var fn = function() {2. this.foobar = "foo";3. };3. };4.5. var obj = new fn;6. obj.foobar; // foo
1. var fn = function() {2. this.foobar = "foo";3. };4.5. var bar = fn();6. bar.foobar; // error
this, which is hard to define
this• this as a context1. var obj = {2. property: "foo",3. method: function() {4. return this.property;5. }5. }6. };7.8. obj.method(); // "foo"
;
this• this as a context1. var fn = function() {2. this.foobar = "foo";3. };4.5. var bar = fn();5. var bar = fn();6. bar.foobar; // error7. foobar; // "foo" !
this
What is the value of res.foobar?
Exercise
1. var e = !!3;2. var fn = function() { 2. var fn = function() { 3. return {4. foobar: this.e,5. e: !!06. };7. };8.9. var res = fn();10.res.foobar; // ?
this
What is the value of res.foobar?
Exercise - solution
1. var e = !!3;2. var fn = function() { 2. var fn = function() { 3. return {4. foobar: this.e,5. e: !!06. };7. };8.9. var res = fn();10.res.foobar; // true
this
What is the type of the value returned by
Exercise
1. var foo = { 2. bar: function(){ return this.f; }, 2. bar: function(){ return this.f; }, 3. f: 1 4. };5. var f = foo.bar;6. typeof f(); // ?
What is the type of the value returned by f()?
bar: function(){ return this.f; }, bar: function(){ return this.f; },
this
What is the type of the value returned by
Exercise - solution
1. var foo = { 2. bar: function(){ return this.f; }, 2. bar: function(){ return this.f; }, 3. f: 1 4. };5. var f = foo.bar;6. typeof f(); // "function"
What is the type of the value returned by f()?
bar: function(){ return this.f; }, bar: function(){ return this.f; },
this
What is the final result of this code?
Exercise
1. var foo = { 2. bar: function(){ return this.foobar; }, 2. bar: function(){ return this.foobar; }, 3. foobar: 1 4. };5.6. typeof (xxx = foo.bar)(); // ?
bar: function(){ return this.foobar; }, bar: function(){ return this.foobar; },
this
What is the final result of this code?
Exercise - solution
1. var foo = { 2. bar: function(){ return this.foobar; }, 2. bar: function(){ return this.foobar; }, 3. foobar: 1 4. };5.6. typeof (xxx = foo.bar)(); // "undefined"
bar: function(){ return this.foobar; }, bar: function(){ return this.foobar; },
// "undefined"
windowwindowwindowwindow
window• window as a context1. var fn = function() {2. this.foobar = "foo";3. };4.5. fn();5. fn();6. foobar; // foo !
1. var fn = function() {2. this === window; // true3. };4.5. fn();
window• window as a context1. <script type="text/javascript">2. var fn = function() {3. alert(window === this); 4. };5. fn();5. fn();6. </script>
1. <script type="text/javascript">2. alert(window === this); // true3. </script>
alert(window === this); // true
// true
window• window as a global object1. <script type="text/javascript">2. var global = (function() { return this; })();3. window === global; // true4. </script>
var global = (function() { return this; })();
window• curiosities1. <script type="text/javascript">2. var x = "foobar" in window; 3. var foobar = 2;4. </script>
1. <script type="text/javascript">2. alert(window['foobar']); // undefined3. var foobar = 2;4. alert(window['foobar']); // 25. </script>
// true
// undefined
// 2
window is a browser global window is a browser global object!
window is a browser global window is a browser global object!
Functions are objectsFunctions are objectsFunctions are objectsFunctions are objects
Functions are objects• basics1. var fn = function() {};2. fn.foobar = "2";3. fn.foobar; // 2
1. var fn = function() {};1. var fn = function() {};2. fn.method = function() { return this === fn; }; 3. fn.method(); // true
fn.method = function() { return this === fn; };
Functions are objects• basics1. var fn = function() {};2. fn.method = function() { return "foobar"; }3. var obj = new fn;4. obj.method(); // error
• why is an error here?
fn.method = function() { return "foobar"; }
Functions are objects• Function constructor1. var fn = Function("return \"foobar2. fn(); // "foobar"
1. var fn = Function("return \"foobar2. typeof fn; // function2. typeof fn; // function
1. var fn = new Function("return \"foobar2. typeof fn; // function
1. var fn = new Function("return \"foobar2. fn.toString(); // "function anonymous() { return "foobar"; }"
1. var fn = Function("return \"foobar2. fn.constructor.toString(); 3. // "function Function() { [native code] }"
"foobar\"");
"foobar\"");
"foobar\"");
"foobar\"");"function anonymous() { return "foobar"; }"
"foobar\"");
"function Function() { [native code] }"
Functions are objects• Function constructor and the prototype chain1. var fn = Function("return \"foobar2. fn.__proto__.constructor; // Function [native]3. fn.__proto__.__proto__.constructor;
1. var fn = function() { return "foobar"1. var fn = function() { return "foobar"2. fn.__proto__.constructor; // Function [native]3. fn.__proto__.__proto__.constructor;
1. var fn = function() { return "foobar"2. fn.__proto__.constructor; // Function [native]3. fn.__proto__.__proto__.constructor; 4. fn.__proto__.__proto__.__proto__;
Function constructor and the prototype chain"foobar\"");Function [native]
fn.__proto__.__proto__.constructor; // Object [native]
return "foobar"; };return "foobar"; };Function [native]
fn.__proto__.__proto__.constructor; // Object [native]
return "foobar"; };Function [native]
fn.__proto__.__proto__.constructor; // Object [native]fn.__proto__.__proto__.__proto__; // null
Functions are objects• IE vs Firefox1. if (true) {2. function fn() {};3. } else {4. function fn() { return 2; }5. }5. }6.7. alert(fn);
1. var fn = function some() {};2. alert(typeof fn);
Functions are objects• anonymous functions1. var fn = function(name, f) {2. return {3. name: name,4. fn: f5. };5. };6. };7.8. var multiple = fn("any function", function(x, y) { return x *
y; });9. multiple.fn(2, 3); // 6
var multiple = fn("any function", function(x, y) { return x *
Functions are objects• .call1. var fn = function(a, b) {2. return a * this + b;3. };4.5. fn.call(5, 1, 2);5. fn.call(5, 1, 2);
Functions are objects• .call1. var fn = function(a, b) {2. return a * this + b;3. };4.5. fn.call(5, 1, 2); // 75. fn.call(5, 1, 2); // 7
Functions are objects• .call1. var fn = function() {2. return this;3. };4.5. var obj = { foobar: "foobar" };5. var obj = { foobar: "foobar" };6. obj === fn.call(obj);
Functions are objects• .call1. var fn = function() {2. return this;3. };4.5. var obj = { foobar: "foobar" };5. var obj = { foobar: "foobar" };6. obj === fn.call(obj); // true !
Functions are objects• .apply1. var fn = function(a, b, c) {2. return a + b + c;3. };4. fn.apply(this, [1, 2, 3]);
Functions are objects• .apply1. var fn = function(a, b, c) {2. return a + b + c;3. };4. fn.apply(this, [1, 2, 3]); // 6
Functions are objects• .call and .apply
– .call requires every single argument– .apply requires only the arguments array– .apply > .call?
• usage:• usage:– callbacks– JAVA-like class abstractions– event handlers– many others
.call requires every single argument
.apply requires only the arguments array
.call
What is the result of this code?
Exercise
1. var fn = function() {2. return this;2. return this;3. };4. fn.call(null); // ?
.call
What is the result of this code?
Exercise
1. var fn = function() {2. return this;2. return this;3. };4. fn.call(null); // window
argumentsargumentsargumentsarguments
Functions are objects• what is arguments?1. var fn = function(a, b, c) {2. return arguments[1];3. };4. fn(1, 2, 3); // 2
• arguments and "object-like" array1. var fn = function(a, b, c) {2. return arguments.length;3. };4. fn(1, 2, 3); // 3
like" array
Functions are objects• why is not arguments the proper array?1. var fn = function(a) {2. return arguments.constructor; 3. };
1. var arr = [];1. var arr = [];2. arr.constructor; // Array
1. var fn = function(a) {2. return arguments.pop(); // error 3. };
the proper array?
.constructor; // Object
// error !
Functions are objects• how to convert arguments to a real array?1. var fn = function(a) {2. var args = Array.prototype.slice.call(arguments);3. alert(typeof args.pop); // "function"4. };
• might be helpful1. var fn = function(a) {2. arguments[0] = 5;3. return a;4. };5.6. fn(2); // 5;
to a real array?
var args = Array.prototype.slice.call(arguments);// "function"
Functions are objects• why useful?
– handling unpredictable numbers of arguments1. var add = function() {2. for (var i = 0, l = arguments.length, sum = 0; i < l; i++) {3. sum += arguments[i];
– validating the number of arguments
3. sum += arguments[i];4. }5. };6.7. add(2, 3, 4); // 9
handling unpredictable numbers of arguments
for (var i = 0, l = arguments.length, sum = 0; i < l; i++) {
validating the number of arguments
Functions are objects• why useful?1. var fn = function(a, b) {2. if (typeof a === "undefined" && typeof b === "undefined"){3. throw new Error("Two arguments required!");
4. };
1. var fn = function(a, b) {2. if (arguments.length < 2){3. throw new Error("At least two arguments
required!"); }4. };
if (typeof a === "undefined" && typeof b === "undefined"){throw new Error("Two arguments required!"); }
throw new Error("At least two arguments
Functions are objects• fn.length
– returns the number of arguments, that you declared with the function
1. var fn = function(a, b) {};2. fn.length; // 2;2. fn.length; // 2;
1. var fn = function(a, b) {};2. fn.length; // 23. fn.length = 4;4. fn.length; // 2
returns the number of arguments, that you declared with
Functions are objects• fn.length
– thinking about arguments number validation1. var fn = function(a, b) {2. if (arguments.length !== fn.length) {3. throw new Error("This function requires at least two 3. throw new Error("This function requires at least two
arguments passed!");4. }5. };6.7. fn();
thinking about arguments number validation
if (arguments.length !== fn.length) {This function requires at least two This function requires at least two
Functions are objects
Try to implement addMethod function,overloading
Exercise
1. var obj = {2. property: "foobar"2. property: "foobar"3. };4.5. addMethod(obj, "methodName", function(a) { return6. addMethod(obj, "methodName", function(a, b) { return a + b; });7. addMethod(obj, "methodName", function() { return 2; });8.9. obj.methodName(1); // 110.obj.methodName(2, 3); // 511.obj.methodName(); // 2
function, which would simulate method
addMethod(obj, "methodName", function(a) { return a; });addMethod(obj, "methodName", function(a, b) { return a + b; });addMethod(obj, "methodName", function() { return 2; });
Anonymous recursionAnonymous recursionAnonymous recursionAnonymous recursion
Anonymous recursion
1. var factorial = function(x) {2. if (x > 0) {3. return x * arguments.callee(x4. }
• arguments.callee
4. }5. return 1;6. };7.8. factorial(4); // 24
• deprecated in strict mode!
arguments.callee(x-1);
deprecated in strict mode!
Anonymous recursion
1. var factorial = function factorial2. if (x > 0) {3. return x * factorial(x4. }
• a bit different
4. }5. return 1;6. };7.8. factorial(4); // 24
factorial(x) {
(x-1);
ArraysArraysArraysArrays
Arrays• there is no "array" type
• associative arrays are object literals, only!
1. var arr = [];2. typeof arr; // "object"
• associative arrays are object literals, only!1. var colors = {};2. colors['green'] = 0;3. colors['blue'] = 1;4. etc...
associative arrays are object literals, only!associative arrays are object literals, only!
Arrays
Try to implement a simple CustomMap associative array and has three methods: add(key, value), remove(key), getLength.
Exercise
1. var CustomMap = function() { ...1. var CustomMap = function() { ...2. var colors = new CustomMap;3.4. colors.add("green", 0);5. colors.add("blue", 1);6.7. colors.getValue("blue"); // 18. colors.remove("blue");9. colors.getLength(); // 1
CustomMap constructor, which works like an associative array and has three methods: add(key, value), remove(key),
};};
Arrays• removing array elements –
• right approach
1. var arr = [1, 2, 3];2. delete arr[1]; // true3. arr.length; // 3
• right approach
• .splice returns an array of the elements removed
1. var arr = [1, 2, 3];2. arr.splice(1, 1);3. arr.length; // 2
1. var arr = [1, 2, 3];2. arr.splice(1, 1)[0]; // 2
wrong approach
returns an array of the elements removed
Arrays• cloning arrays
– slice
– concat
1. var arr = [1, 2, 3];2. var newArr = arr.slice(0);
– concat• .splice zwraca tablicę usuniętych elementów1. var arr = [1, 2, 3];2. var newArr = [].concat(arr);
zwraca tablicę usuniętych elementów
Arrays• merging arrays
– jQuery approach (merges either arrays or objects)
– concat
1. var i = first.length, j = 0;2. if ( typeof second.length === "number" ) { 3. for ( var l = second.length; j < l; j++ ) {
– concat• .splice zwraca tablicę usuniętych elementów
3. for ( var l = second.length; j < l; j++ ) { 4. first[ i++ ] = second[ j ]; 5. } 6. } else { 7. while ( second[j] !== undefined ) { 8. first[ i++ ] = second[ j++ ]; 9. } 10.}11.12.first.length = i; 13.return first;
jQuery approach (merges either arrays or objects)
if ( typeof second.length === "number" ) { for ( var l = second.length; j < l; j++ ) {
zwraca tablicę usuniętych elementów
for ( var l = second.length; j < l; j++ ) { first[ i++ ] = second[ j ];
while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ];
Arrays• merging arrays
– push1. var arr = [1, 2, 3];2. arr.push.apply(arr, [3, 4, 5]);3. arr; // [1, 2, 3, 3, 4, 5]3. arr; // [1, 2, 3, 3, 4, 5]
Arrays• forEach
– JavaScript 1.6 - Firefox1. var arr = [1, 2, 3];2. arr.forEach(function(i) {3. alert(i); 3. alert(i); 4. });
Arrays
Implement your own forEach method when it is not supported by the browser engine.
Exercise
method when it is not supported by the
ArraysExercise - solution
1. if (!Array.prototype.forEach) {2. Array.prototype.forEach = function(callback) {3. if (typeof callback === "function") {3. if (typeof callback === "function") {4. for (var i = 0, j = this.length; i < j; i++) {5. callback.call(this, i);6. }7. }8. };9. }
Array.prototype.forEach = function(callback) {if (typeof callback === "function") {if (typeof callback === "function") {
for (var i = 0, j = this.length; i < j; i++) {callback.call(this, i);
Arrays• max value inside the array
• min value inside the array
1. var arr = [1, 2, 3];2. Math.max.apply(Math, arr); // 3
• min value inside the array1. var arr = [1, 2, 3];2. Math.min.apply(Math, arr); // 1
Classical objects and classes Classical objects and classes approach
Classical objects and classes Classical objects and classes approach
JavaScript !== JavaJavaScript !== JavaJavaScript !== JavaJavaScript !== Java
What things is JavaScript missing?• class keyword and similar ones• extends keyword• methods and operators overloading• public, protected, private accessors• public, protected, private accessors• static typing• abstraction classes, interfaces• and much more
What things is JavaScript missing?keyword and similar ones
methods and operators overloadingaccessorsaccessors
abstraction classes, interfaces
What things is JavaScript missing?• I have been writing JavaScript for 8 years now, and I
have never once found need to use an uber function. The super idea is fairly important in the classical pattern, but it appears to be unnecessary in the prototypal and functional patterns. I now see in the prototypal and functional patterns. I now see my early attempts to support the classical model in JavaScript as a mistake.
What things is JavaScript missing?I have been writing JavaScript for 8 years now, and I have never once found need to use an uber function. The super idea is fairly important in the classical pattern, but it appears to be unnecessary in the prototypal and functional patterns. I now see in the prototypal and functional patterns. I now see my early attempts to support the classical model in
Douglas Crockfordhttp://crockford.com
Public properties• object literals1. var obj = {2. method: function() {},3. property: 10004. };
• constructors1. var klass = function() {2. this.method = function() {};3. this.property = 1000;4. };5. var obj = new klass;6. obj.property;7. obj.method();
Take care of prototypes!Take care of prototypes!Take care of prototypes!Take care of prototypes!
Public properties• constructor1. var klass = function() {2. this.property = 1000;3. };4.4.5. klass.prototype.method = function() {};6.7. var obj = new klass;8. obj.property;9. obj.method();
klass.prototype.method = function() {};
Reusable code!Reusable code!Reusable code!Reusable code!
Private properties• object literals1. var obj = (function() {2. var priv = 200;3. return {4. method: function(){},5. method2: function() {},5. method2: function() {},6. property: 10007. };8. })();9. obj.priv; // undefined
method: function(){},method2: function() {},method2: function() {},
Private properties• constructors1. var klass = function() {2. var priv = 200;3.4. this.method = function() {};5. this.property = 1000;5. this.property = 1000;6. };7.8. var obj = new klass;9. obj.priv; // undefined
Prototypal inheritance1. var base = function() {2. this.method = function() { return 100; };3. };4.5. var child = function() {6. this.method2 = function() { return 200; }6. this.method2 = function() { return 200; }7. };8.9. child.prototype = new base; !10.11.var obj = new child;12.obj.method(); // 10013.obj instanceof base; // true
this.method = function() { return 100; };
this.method2 = function() { return 200; }this.method2 = function() { return 200; }
Functional inheritance1. var base = function() {2. return {3. method: function() { return 100; };4. };5. };6.7. var child = function() {6.7. var child = function() {8. var that = base();9. that.method2 = function() {10. return 200;11. };12. return that;13.};14.15.var obj = new child;16.obj.method(); // 100
method: function() { return 100; };
Class abstractions• mootools – http://mootools.net1. var Animal = new Class({2. initialize: function(age){3. this.age = age;4. }5. });5. });6. var Cat = new Class({7. Extends: Animal,8. initialize: function(name, age){9. this.parent(age); //will call initalize of Animal10. this.name = name;11. }12.});13.var myCat = new Cat('Micia', 20);14.alert(myCat.name); // 'Micia'15.alert(myCat.age); // 20
mootools.net
initialize: function(name, age){this.parent(age); //will call initalize of Animal
var myCat = new Cat('Micia', 20);
Class abstractions• jQuery - http://code.google.com/p/jquery1. Animal = $.klass({2. init: function( sound ) {3. this.sound = sound;4. },5. say: function( msg ) {6. alert( this.sound + ', ' + msg );6. alert( this.sound + ', ' + msg );7. }8. });9. Dog = $.klass( Animal, {10. init: function( name ) {11. this.name = name;12. this.up( arguments, 'Woof Woof' );13. },14. say: function( msg ) {15. this.up( arguments, this.name + ': ' + this.noise + msg );16. }17.});
code.google.com/p/jquery-klass
alert( this.sound + ', ' + msg );alert( this.sound + ', ' + msg );
this.up( arguments, 'Woof Woof' );
this.up( arguments, this.name + ': ' + this.noise + msg );
Namespacing• what are namespaces?• example usage1. var com = {};2. com.testApp = {};3.3.4. com.testApp.utils = {5. trim: function() {}6. };7.8. com.testApp.utils.trim();
Namespacing• single namespaces1. var app = {};2.3. app.options = {4. foobar: "foo",5. bar: "bar"
• risks• performance
5. bar: "bar"6. };7. app.events = {};8. etc...
Singleton pattern in JavaScript• :1. const Singleton = (function(){2. var Constructor = function() {3. this.data = 'some data';4. }, instance = null;5.6. return {7. getInstance: function (){6. return {7. getInstance: function (){8. return instance || (instance = new Constructor);9. }10. };11.})();
Singleton pattern in JavaScript
var Constructor = function() {this.data = 'some data';
getInstance: function (){getInstance: function (){return instance || (instance = new Constructor);
What's about object literals!?What's about object literals!?What's about object literals!?What's about object literals!?
Factory pattern in JavaScript• :1. var Person = (function () {2. var Person = function (name, location) {3. this.name = name;4. this.location = location;5. };6.6.7. return function (name, location) {8. return new Person(name, location);9. };10.})();
Factory pattern in JavaScript
var Person = function (name, location) {
this.location = location;
return function (name, location) {return new Person(name, location);
bind()bind()bind()bind()
bind()• :1. Function.prototype.bind = function(obj) {2. var fn = this;3. var args = Array.prototype.slice.call(arguments);4.5. return function() {6. var args2 = Array.prototype.slice.call(arguments);7. return fn.apply(obj, args.concat(args2)); 7. return fn.apply(obj, args.concat(args2)); 8. }9. }10.11.var fn = function() {12. alert(this);13.};14.15.fn = fn.bind("foobar");16.fn(); // "foobar"
Function.prototype.bind = function(obj) {
var args = Array.prototype.slice.call(arguments);
args2 = Array.prototype.slice.call(arguments);fn.apply(obj, args.concat(args2)); // !fn.apply(obj, args.concat(args2)); // !
curryingcurryingcurryingcurrying
Currying• :1. Function.prototype.curry = function() {2. var fn = this;3. var args = Array.prototype.slice.call(arguments); 4.5. return function() {6. var args2 = Array.prototype.slice.call(arguments); 7. return fn.apply(this, args.concat(args2)); 7. return fn.apply(this, args.concat(args2)); 8. }9. }10.11.var fn = function(a, b) {12. alert(b);13.};14.15.var otherFn = fn.curry("bla bla");16.otherFn(2); // 2
Function.prototype.curry = function() {
var args = Array.prototype.slice.call(arguments); // ["bla bla"]
args2 = Array.prototype.slice.call(arguments); // [2]fn.apply(this, args.concat(args2)); // ["bla bla", 2]fn.apply(this, args.concat(args2)); // ["bla bla", 2]
chainingchainingchainingchaining
Chaining• :1. var chaining = (function() {2. return {3. method1: function() { 4. alert("one"); 5. return this; //6. },7. method2: function() { 7. method2: function() { 8. alert("two"); 9. return this; //10. }11. };12.})();13.14.chaining.method1().method2();
// !
// !
Code optimizationCode optimizationCode optimizationCode optimization
http://www.slideshare.net/http://www.slideshare.net/madrobby/extreme
javascript-performance
www.slideshare.net/www.slideshare.net/madrobby/extreme-
performance
Avoid functions callingAvoid functions callingAvoid functions callingAvoid functions calling
Code optimization• :1. while (i) {2. fn(i);3. var i = fn2();4. fn3(i);5. };
Use local variables!Use local variables!Use local variables!Use local variables!
Code optimization• :1. var fn = function() {2. var events = library.utils.events;3. var proxy = library.services.proxy;4. };
var events = library.utils.events;var proxy = library.services.proxy;
Avoid try{} catch() {} Avoid try{} catch() {} Avoid try{} catch() {} Avoid try{} catch() {}
Take care of for loopsTake care of for loopsTake care of for loopsTake care of for loops
Code optimization• :1. var arr = [1, 2, 3, 4];2. for (var i = 0; i < arr.length; i++) {};
1. var arr = [1, 2, 3, 4];2. for (var i = 0, j = arr.length; i < j; i++) {};
1. var arr = [1, 2, 3, 4];2. var i = arr.length;3. while(i--) {};
for (var i = 0; i < arr.length; i++) {};
for (var i = 0, j = arr.length; i < j; i++) {};
Code optimization
Write a function which multiplies every second array element by two.
ExerciseWrite a function which multiplies every second array element by two.
memoization memoization memoization – remember!memoization – remember!
Optimization - memoization• :1. var arr = [1, 2, 3, 4, 4, 2, 3, 1, 2, 3, 4, 5, 6, 1];2. var fn = function fn(i) {3. fn.cache = fn.cache || {};4. return fn.cache[i] || (fn.cache[i] = Math.cos(i));
is wrong here?5. };
1. var arr = [1, 2, 3, 4, 4, 2, 3, 1, 2, 3, 4, 5, 6, 1];2. var fn = function fn(i) {3. fn.cache = fn.cache || {};4.5. if (i in fn.cache) {6. return fn.cache[i];7. }
8. return (fn.cache[i] = Math.cos(i));9. };
memoizationvar arr = [1, 2, 3, 4, 4, 2, 3, 1, 2, 3, 4, 5, 6, 1];
return fn.cache[i] || (fn.cache[i] = Math.cos(i)); // what
var arr = [1, 2, 3, 4, 4, 2, 3, 1, 2, 3, 4, 5, 6, 1];
return (fn.cache[i] = Math.cos(i));
yieldingyieldingyieldingyielding
~~(1 * "2.22") ~~(1 * "2.22") faster than
parseInt("2.22")
~~(1 * "2.22") ~~(1 * "2.22") faster than
parseInt("2.22")
Simpler Simpler Simpler - fasterSimpler - faster
Code optimization• slow
• fast
1. var min = Math.min(a, b);2. arr.push(val);
• fast1. var min = a < b ? a : b;2. arr[arr.length] = val;
Thanks!Thanks!Thanks!Thanks!
Rafał KukawskiRafał Kukawskihttp://blog.kukawski.pl
review, proofreading
Rafał KukawskiRafał Kukawskihttp://blog.kukawski.pl
review, proofreading
Lea VerouLea Verouhttp://leaverou.me
proofreading
Lea VerouLea Verouhttp://leaverou.me
proofreading