Just Advanced JavaScript

  • 19,532 views
Uploaded on

Over 200 helpful slides about advanced JavaScript.

Over 200 helpful slides about advanced JavaScript.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
19,532
On Slideshare
0
From Embeds
0
Number of Embeds
7

Actions

Shares
Downloads
1,034
Comments
4
Likes
67

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Just Advanced JavaScript
  • 2. Damian Wielgosik http://varjs.com varjs.com http://ferrante.pl
  • 3. ECMA Standard
  • 4. http://www.ecma- http://www.ecma international.org/ publications/files/ECMA-ST/ publications/files/ECMA ECMA-262.pdf
  • 5. ECMA Standard • What is ECMA? • ECMAScript and JavaScript • history • ECMA 262 • future – desktop – server-side – iPhone WebKit, Nokia WRT – Nintendo Wii – OLPC (One laptop per child) – ...
  • 6. 0.1 + 0.2 !== 0.3 ECMA bad parts
  • 7. JScript
  • 8. JScript • Debug • Enumerator • VBArray • ActiveXObject • GetObject() • @cc_on • (new Data).getVarDate() • host objects
  • 9. JavaScript 1.5
  • 10. JavaScript 2.0
  • 11. Browsers
  • 12. JavaScript – go!
  • 13. JavaScript – go! • attaching scripts to your site 1. <script type="text/javascript" src="script.js"></script> 1. <script type="text/javascript"> 2. var win = window; 3. //... 4. </script> • charset 1. <script type="text/javascript" src=" src="script.js" charset="utf-8"> • version 1. <script type="application/javascript;version=1.8" src="script.js" charset="utf-8"> 8">
  • 14. Asynchronous Loading
  • 15. Asynchronous Loading • why Asynchronous Loading? • basic usage: 1. var script = document.createElement("script"); 2. script.type = "text/javascript"; 3. script.src = "someScript.js"; 4. document.body.appendChild(script); • or just put <script></script> before </body>
  • 16. Lazy Loading
  • 17. 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): 1. LazyLoad.load('http://example.com/foo.js', loadComplete); 2. LazyLoad.load('http://example.com/bar.js', loadComplete, this, true);
  • 18. Code compression
  • 19. Code compression • why to compress JavaScript code? – less HTTP traffic – faster load time • code minification – Dean Edwards packer • http://dean.edwards.name/packer dean.edwards.name/packer – Google kit • http://code.google.com/closure/compiler ://code.google.com/closure/compiler – YUI Compressor • http://developer.yahoo.com/yui/compressor developer.yahoo.com/yui/compressor • GZIP • obfuscation
  • 20. Advanced basics
  • 21. Advanced basics • how we used to write JavaScript code – good and bad parts • variables and types • operators • functions • arrays • statements • falsy values • == vs === • bitwise operators
  • 22. How we used to write JavaScript code – good and bad parts
  • 23. Writing JavaScript code – good and bad parts Exercise What can you say about your JavaScript code? Do you like this language? What does just annoy you?
  • 24. Writing JavaScript code – good and bad parts 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.};
  • 25. Writing JavaScript – good and bad parts 1. function show() { 2. var article = document.getElementById("id"); 3. article.style.display = "block"; 4. //... 5. someVar = "oh yeah"; 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.};
  • 26. Writing JavaScript – good and bad parts 1. <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();
  • 27. Good parts - a blessing in disguise?
  • 28. Writing JavaScript code – good and bad parts • 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?
  • 29. Writing JavaScript code – good and bad parts Exercise Try to shorten the numbers declarations 1. var n = 124500000; 2. var n2 = 0.00005;
  • 30. Writing JavaScript code – good and bad parts Exercise - solution Try to shorten the numbers declarations 1. var n = 1245e5; 2. var n2 = 5e-5;
  • 31. JavaScript – where hacking begins!
  • 32. Variables and types
  • 33. Variables • var is your friend 1. var barfoo; // undefined, is a default value of every variable 2. var foobar = "string"; 3. var foobar = -5; // dynamic typing, no type control 4. var foo = function() { return 5; }; // function as variables 5. var bar = 2e3; // 2000 6. var barbar = Number.Infinity; 7. var foofoo = null; 8. var dec = .3; // the other way to write float numbers 9. var hex = 0xF; // 15 written in hex 10.var t = new Date().getTime(); // UNIX timestamp e.g. 1262184428510 • declaring many variables at one time 1. var foobar = "string", 2. foo = function() {}, 3. bar = 2e3;
  • 34. typeof
  • 35. Variable types • string 1. var foobar = "variable types"; 2. typeof foobar; // "string" • number 1. var foobar = 0.5; 2. typeof foobar; // "number" 3. var foobar = 1; 4. typeof foobar; // "number" • boolean 1. var foobar = true; 2. typeof foobar; // "boolean"
  • 36. Variable types • function 1. var foobar = function() {}; 2. typeof foobar; // "function" • object 1. var foobar = {}; 2. typeof foobar; // "object" • undefined 1. var foobar; 2. typeof foobar; // "undefined"
  • 37. What about null?
  • 38. typeof null == "object" 1. var foobar = null; 2. typeof foobar; // "object"
  • 39. NaN
  • 40. NaN • paradoxical type 1. var foobar = NaN; 2. typeof foobar; // "number" • watch out, easy to overwrite! 1. var NaN = "string"; 2. typeof NaN; // "string" • getting NaN 1. var foobar = "string" * 2, bar = "string" / 2; 2. var foo = +"string", barfoo = +[1, 2, 3], foobar2 = undefined – 2;
  • 41. Operators
  • 42. Assigment operator "=" • "=" – multiple assigments 1. 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 left
  • 43. "+" operator • string concatenation 1. var foobar = "This " + "is " + "a variable."; • casting to number ("number" type) 1. var foobar = +true; // 1 2. var foobar = +false; // 0 • adding 1. var foobar = 5 + 1; // 6 • string priority 1. var foobar = "1" + 0; // 10 ! 2. typeof foobar; // "string" 3. var foobar = 0 + "1"; // 01 4. typeof foobar; // "string"
  • 44. toString() == "" + 1. var foobar = function() {}; 2. var foobar2string = "" + foobar; // "function() {}" 3. typeof foobar2string; // "string"
  • 45. (new Date).getTime() == +new Date
  • 46. Operators "+=" and "++" • forget about var 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"
  • 47. Operators "+=" and "++" • multiple assigments 1. 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";
  • 48. Operators "-=" and "--" • forget about var 1. var foobar = 1; 2. foobar -= 1; // 0 • -= does not behave like += = 1. var foobar = "1"; 2. foobar -= 5; // -4 (number) ! • // number 1. var foobar = "5"; 2. foobar--; 3. // 4 4. typeof foobar; // "number"
  • 49. Operators "-=" and "--" • multiple assigments 1. 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 == NaN 5. // bar == NaN
  • 50. "||" operator • assigment 1. var foo = false; 2. var bar = function() {}; 3. var foobar = foo || bar; // foobar === bar 4. foobar(); 1. var foo = true; 2. var bar = function() {}; 3. var foobar = foo || bar; // foobar === true 4. foobar(); // error 1. var foo = false; 2. var bar = false; 3. var barfoo = 5; 4. var foobar = foo || bar || barfoo; // foobar === 5
  • 51. "&&" operator • assigment 1. var foo = true; 2. var bar = function() {}; 3. var foobar = foo && bar; // foobar === bar 4. foobar(); 1. var foo = false; 2. var bar = function() {}; 3. var foobar = foo && bar; // foobar === false 4. foobar(); // error • inline conditions 1. var foo = true; 2. var bar = function() { alert("hello world!"); }; 3. foo && bar(); // hello word!
  • 52. Operators "&&" and "||" • good order makes a difference 1. var foo = true; 2. var bar = false; 3. var barfoo = false; 4. var foobar = foo && bar || barfoo || 5; // foobar === 5 !
  • 53. "!" as a negation operator • converts to bool 1. var foo = 5; 2. !foo; // false 3. var foo = 0; 4. !foo; // true 5. var foo = "0"; 6. !foo; // false 7. var foo = "1"; 8. !foo; // false • double negation 1. var foo = 5; 2. !!foo; // true
  • 54. The power of "~" • bitwise operator • numbers rounding 1. var foo = 5.743534; 2. ~~foo; // 5 3. typeof ~~foo; // "number" ! • - (n + 1) when "n" is an integer 1. var foo = -1; 2. ~foo; // 0 1. var default = -1; 2. if (!~default) { }; // if default remains -1
  • 55. Arrays
  • 56. Arrays • declaration 1. var foo = []; 2. foo.length; // 0 3. typeof foo; // "object" ! 1. var foo = [, , ,]; 2. foo.length; // 4 (IE) or 3 (Firefox) 3. typeof foo[2]; // "undefined" 4. [1, function() {}, null].length // 3 • forget about new Array 1. var foo = new Array([2, 3, 4].length); 2. foo.length; // 3 3. typeof foo[2]; // "undefined" 4. var Array = 100; 5. var foo = new Array([2, 3, 4].length); // error
  • 57. Arrays • forget about new Array 1. var foo = []; 2. var len = 5; 3. 4. foo[len-1] = undefined; 5. foo.length; // 5 6. typeof foo[2] // "undefined"
  • 58. Arrays Exercise What is the result of following code: var x = [typeof 5, typeof null][1]; ][1]; typeof typeof x; // ?
  • 59. Arrays Exercise - solution What is the result of following code: var x = [typeof 5, typeof null][1]; ][1]; typeof typeof x; // "string"
  • 60. Functions
  • 61. Functions • declaration 1. var foo = function() { return 5; }; 2. foo(); // 5 1. function foo() { return 5; }; 2. foo(); // 5 1. var foo = function foo() { return 5; }; 2. foo(); // 5 • anonymous functions as arguments 1. var f = function() { alert("hello world!"); }; 2. var foobar = function(fn) { 3. fn(); 4. } 5. foobar(f); // hello world!
  • 62. Functions • one function can return another function 1. var foo = function() { return function() {}; }; 2. foo(); // function() {};
  • 63. Function declarations matter
  • 64. http://yura.thinkweb2.com/named -function-expressions expressions
  • 65. Functions Exercise #1 What is the result of fn()? var i = 5; var fn = function() { return i++; }; fn(); // ? Exercise #2 What is the result of typeof fn()? var fn = function() {}; typeof fn(); // ?
  • 66. Functions Exercise #1 - solution What is the result of fn()? var i = 5; var fn = function() { return i++; }; fn(); // 5 Exercise #2 - solution What is the result of typeof fn()? var fn = function() {}; typeof fn(); // "undefined"
  • 67. Statements
  • 68. Conditional statements • if conditional statements without the braces 1. if (true) 2. fn(); 1. if (true) 2. fn(); 3. else 4. fn2(); 5. fn3(); // out of statement ! • inline conditions 1. var foo = true, bar = false; 2. foo && fn(); 3. var foo = false, bar = true; 4. foo && fn() || bar && fn2();
  • 69. Conditional statements • ternaly operator 1. var fn = function() { return false; }; 2. var val = fn() ? "true" : "false"; 3. val; // "false"
  • 70. Loops • for loop without the braces 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 braces 1. while(i--) 2. j -= i; 1. while(i--) 2. j -= i; 3. j *= 2; // out of the loop! !
  • 71. Falsy values
  • 72. Falsy values • what are falsy values? • falsy values: – null – undefined – 0 – NaN – "" – false
  • 73. Falsy values • examples 1. var falsyValue = 0; 2. if (!falsyValue) { 3. alert("falsy value!"); 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...
  • 74. Falsy values • risks 1. var falsyValue = ""; 2. if (falsyValue == 0) { 3. alert("falsy value!"); 4. } 5. var falsyValue; 6. if (falsyValue == null) { 7. alert("falsy value!"); 8. } 9. // etc...
  • 75. == versus ===
  • 76. == versus === Exercise What are the results of following comparisons var foo = null; var bar; foo == bar; // ? 10 == "10"; // ? "1e1" == 10; // ? "" === new String(""); // ? 0 == null // ?
  • 77. == versus === Exercise - solution What are the results of following comparisons? var foo = null; var bar; foo == bar; // true 10 == "10"; // true "1e1" == 10; // true "" === new String(""); // false 0 == null // false
  • 78. == versus === • avoid == – unexpectable behaviour 1. ' trn ' == 0 // true – ECMA spec page 80. – possible usage: 1. if (typeof fn == "function") { // ... } • typeof 1. if (typeof string == "string") { // ... } • === is an effective solution – checks and compares the value and the type of variable
  • 79. == versus === • examples === 1. var falsyValue = ""; 2. if (falsyValue === 0) { // is never true 3. // ... 4. } 5. var falsyValue = false; 6. if (falsyValue === "") { // is never true 7. alert("falsy value!"); 8. } 9. // etc...
  • 80. Hands on bitwise operators
  • 81. Garbage collector
  • 82. Object model in JavaScript
  • 83. Objects in JavaScript • what is an object in JavaScript? • primitives are not the real objects – undefined – strings – numbers – null – false, true • custom object model in JS
  • 84. Object literals
  • 85. Object literals • basics 1. var obj = { 2. property: "foobar", 3. method: function() {} 4. }; 5. typeof obj; // "object" 6. obj.property; // "foobar" 7. obj.method(); • an empty object 1. var obj = {}; • arrays as objects 1. var arr = []; 2. typeof arr; // "object"
  • 86. Object literals • objects can be returned by a function 1. var fn = function() { 2. return { 3. property: "foobar", 4. method: function() {} 5. }; 6. }; 7. typeof fn(); // object 8. fn().property; // "foobar" 9. fn().method(); • two ways to access the object's property 1. obj['property']; 2. obj.property;
  • 87. Functions as constructors
  • 88. Functions as constructors • basics 1. var fn = function() { 2. this.property = "foobar"; 3. this.method = function() {}; 4. }; 5. 6. var obj = new fn; 7. typeof obj; // "object" ! 8. obj.property; // "foobar" 9. obj.method(); // undefined
  • 89. Functions as constructors • inline object initialization 1. var fn = function() { 2. this.property = "foobar"; 3. this.method = function() { 4. return this.property; 5. }; 6. }; 7. 8. typeof new fn; // object ! 9. (new fn).property; // "foobar" 10.(new fn).method(); // "foobar"
  • 90. .constructor
  • 91. .constructor • .constructor property 1. var obj = { 2. property: "foobar", 3. method: function() {} 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...
  • 92. .constructor • .constructor property 1. var fn = function fn() { 2. this.property = "foobar"; 3. this.method = function() {}; 4. }; 5. (new fn).constructor // function fn() { ... }
  • 93. http://joost.zeekat.nl/constructors joost.zeekat.nl/constructors -considered considered-mildly- confusing.html
  • 94. .prototype
  • 95. .prototype • what is .prototype? – .prototype as an object 1. var fn = function() { }; 2. typeof fn.prototype; // "object" – .prototype as a starting point for object creation – prototype chaining • Object.prototype • .prototype in constructors
  • 96. .prototype in constructors 1. var fn = function() { }; 2. fn.prototype = { property: "foobar" }; 3. 4. var obj = new fn; 5. obj.property // "foobar" 1. var fn = function() { this.property = "bar"; }; 2. fn.prototype = { property: "foobar" }; 3. 4. var obj = new fn; 5. obj.property // "bar" 1. var fn = function() { }; 2. fn.prototype.property = function() { alert("hello world!"); }; 3. 4. var obj = new fn; 5. obj.property() // "hello world!"
  • 97. .prototype in constructors • overwritting .prototype property and possible risks 1. var fn = function() { }; 2. fn.prototype = { property: "foobar" }; 3. var obj = new fn; 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
  • 98. .prototype in constructors • updating the .prototype properties 1. var fn = function() { }; 2. fn.prototype.foo = "bar"; 3. 4. var obj = new fn; 5. 6. fn.prototype.foo = "foo"; 7. obj.foo; // "foo" !
  • 99. .prototype in constructors • accessing object properties 1. var fn = function() { 2. this.hello = "hello world!"; 3. }; 4. fn.prototype = { 5. say: function() { alert(this.hello); } 6. }; 7. 8. var obj = new fn; 9. obj.say(); // "hello world!"
  • 100. .prototype in constructors • impact on other object properties 1. var fn = function() { 2. this.hello = "hello world!"; 3. }; 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!"
  • 101. .prototype in constructors Exercise What is the result of typeof obj.foobar? ? 1. var fn = function() { 2. this.foobar = []; 3. }; 4. 5. fn.prototype = { foobar: "foobar" }; 6. 7. var obj = new fn; 8. typeof obj.foobar; // ?
  • 102. .prototype in constructors Exercise - solution What is the result of typeof obj.foobar? ? 1. var fn = function() { 2. this.foobar = []; 3. }; 4. 5. fn.prototype = { foobar: "foobar" }; 6. 7. var obj = new fn; 8. typeof obj.foobar; // "object"
  • 103. Inspecting objects
  • 104. Inspecting objects • for in 1. var obj = { 2. property: "foobar", 3. method: function() {} 4. }; 5. for (var i in obj) { 6. alert("The value of key " + i +" is " + obj[i]); 7. } • hasOwnProperty 1. for (var i in obj) { 2. if (obj.hasOwnProperty(i)) { 3. alert("The value of key " + i +" is " + obj[i]); 4. } 5. }
  • 105. 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) 1. var fn = function() {}; 2. fn.prototype = { property: 2 }; 3. var obj = new fn; 4. obj.__proto__; // { property: 2 }
  • 106. 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" // error 3. }; 1. var obj = { 2. "5": "the key of mine is five" 3. }; 4. obj['5']; // "the key of mine is five the five" 5. obj[5]; // "the key of mine is five the five"
  • 107. toString()
  • 108. toString() 1. var obj = {}; 2. obj.toString(); // "[object Object]" 3. 4. var fn = function() {}; 5. fn.toString(); // "function () { }" 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"
  • 109. What if I overwrite toString?
  • 110. toString() 1. var obj = { 2. toString: function() { 3. alert("Pff, forget about native toString"); 4. } 5. }; 6. 7. for (var i in obj) { 8. alert(i); // IE6+? 9. }
  • 111. instanceof
  • 112. instanceof • what instanceof does 1. var fn = function() {}; 2. var obj = new fn; 3. 4. obj instanceof fn // true • take care 1. var fn = function foobar() {}; 2. var obj = new fn; 3. 4. obj instanceof foobar // error
  • 113. instanceof • instanceof Array is not the best way to do array detection 1. var arr = []; 2. arr instanceof Array // true 1. var Array = function() {}; 2. var arr = []; 3. arr instanceof Array // false
  • 114. Array detection?
  • 115. Object.prototype.toString .call([]) === "[object Array]"
  • 116. instanceof Exercise What is the result of following code? 1. function foo() { return foo; } 2. new foo() instanceof foo; // ?
  • 117. instanceof Exercise - solution What is the result of following code? 1. function foo() { return foo; } 2. new foo() instanceof foo; // false
  • 118. delete
  • 119. delete • delete deletes, in general... 1. var obj = { 2. foo: "bar", 3. bar: "foo" 4. }; 5. typeof obj.foo; // "string" 6. delete obj.foo; 7. typeof obj.foo; // "undefined" • do not delete array elements! 1. var arr = [1, 2, 3]; 2. delete arr[1]; 3. arr.length; // 3; 4. arr.toString(); // 1,undefined,3
  • 120. delete • delete returns boolean 1. var obj = { 2. foo: "bar", 3. bar: "foo" 4. }; 5. 6. delete obj.foo; // true 7. delete obj.foobar; // false 8. delete obj['bar']; // true
  • 121. delete Exercise What does this function return? 1. (function(i){ 2. delete i; 3. return i; // ? 4. })(10);
  • 122. delete Exercise - solution What does this function return? 1. (function(i){ 2. delete i; 3. return i; // 10 4. })(10);
  • 123. http://perfectionkills.com/ perfectionkills.com/ understanding-delete understanding
  • 124. Native constructors (built-in) (built
  • 125. Native constructors • Object • Array • Function • Number • String • RegExp • Boolean
  • 126. Native constructors • Object.prototype 1. Object.prototype.say = function() { alert("hello world!"); }; 2. 3. var obj = {}; 4. obj.say(); // "hello world!" 5. 6. var arr = []; 7. arr.say(); // "hello world!" • Array.prototype 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 3"
  • 127. Native constructors • Function.prototype 1. Function.prototype.say = function() { alert("hello world!"); }; 2. 3. var fn = function() {}; 4. fn.say(); // "hello world!" • itd...
  • 128. Native constructors Exercise #1 Try to implement isEven function which works like following: (5).isEven() -> false Exercise #2 Try to implement normalizeSpaces, which works like following: "Can I haz an hamburger?".normalizeSpaces() -> Can I haz an hamburger?.
  • 129. Native constructors Exercise #1 - solution Try to implement isEven function which works like following: (5).isEven() -> false 1. Number.prototype.isEven = function() { 2. return !(this % 2); 3. }
  • 130. Native constructors Exercise #2 - solution Try to implement normalizeSpaces, which works like following: "Can I haz an hamburger?".normalizeSpaces() -> Can I haz an hamburger?. 1. String.prototype.normalizeSpaces = function() { normalizeSpaces 2. return this.replace(/s+/g, " "); s+/g, 3. };
  • 131. Native constructors • take care – could be overwritten! 1. var Object = 5; 2. Object.prototype.say = function() { alert("hello world!"); }; 3. // error 4. var obj = {}; 5. obj.say(); 1. var Array = function() {}; 2. Array.prototype.say = function() { alert("hello world!"); }; 3. 4. var obj = []; 5. obj.say(); // error
  • 132. Scope
  • 133. Scope • what is "scope"? • blocks range – is there something like that? 1. { 2. var i = 10; 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++) {};
  • 134. Scope • function scope 1. var fn = function() { 2. var i = 10; 3. }; 4. 5. fn(); 6. typeof i; // "undefined" 1. var fn = function() { 2. i = 10; 3. }; 4. 5. fn(); 6. i; // 10
  • 135. Scope • important curiosities 1. var i = 10; 2. var fn = function() { 3. alert(i); // undefined ! 4. var i = 100; 5. alert(i); // 100 6. } 7. 8. fn(); • JavaScript engine scans for "var" declarations and sets the undefined values
  • 136. Scope • important curiosities 1. var fn = function() { 2. var i = 10; 3. var foo = function() { 4. if (i === 10) { 5. var i = 20; 6. } 7. alert(i); // undefined 8. }; 9. foo(); 10.} 11.fn();
  • 137. Scope • important curiosities 1. var arr = [1, 2, 3]; 2. 3. var i = 0; 4. for (var l = arr.length; i < l; i++) { 5. arr[i] = function() { 6. alert(i); 7. }; 8. } 9. 10.arr[0](); // 3 !
  • 138. How it really works?
  • 139. Scope Exercise What is a value of "x" variable? 1. var y = 1, x = y = typeof x; 2. x; // ?
  • 140. Scope Exercise - solution What is a value of "x" variable? 1. var y = 1, x = y = typeof x; 2. x; // "undefined"
  • 141. Closures
  • 142. Closures 1. 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() { 7. alert(i); 8. } 9. })(arr[i]); 10.} 11. 12.arr[0](); // 1 !
  • 143. Closures • self-invoking functions 1. (function() { 2. alert("hello world"); 3. })(); • can take the arguments 1. (function(y, z) { 2. alert(y + z); // 300 3. })(100, 200); • your own space
  • 144. Closures • access to the out-of-scope variables defined in scope outside 1. var fn = function() { 2. var i = 100; 3. 4. var foobar = function() { 5. alert(i); // 100 6. i = 300; 7. }; 8. 9. foobar(); 10. alert(i); // 300 11.};
  • 145. Closures 1. var i = 100; 2. 3. var fn = function(x) { 4. return x * i; 5. }; 6. 7. i = 20; 8. fn(2); // 40
  • 146. this
  • 147. this • this, which is hard to define • this as a context 1. var fn = function() { 2. this.foobar = "foo"; 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
  • 148. this • this as a context 1. var obj = { 2. property: "foo", 3. method: function() { 4. return this.property; ; 5. } 6. }; 7. 8. obj.method(); // "foo"
  • 149. this • this as a context 1. var fn = function() { 2. this.foobar = "foo"; 3. }; 4. 5. var bar = fn(); 6. bar.foobar; // error 7. foobar; // "foo" !
  • 150. this Exercise What is the value of res.foobar? 1. var e = !!3; 2. var fn = function() { 3. return { 4. foobar: this.e, 5. e: !!0 6. }; 7. }; 8. 9. var res = fn(); 10.res.foobar; // ?
  • 151. this Exercise - solution What is the value of res.foobar? 1. var e = !!3; 2. var fn = function() { 3. return { 4. foobar: this.e, 5. e: !!0 6. }; 7. }; 8. 9. var res = fn(); 10.res.foobar; // true
  • 152. this Exercise What is the type of the value returned by f()? 1. var foo = { 2. bar: function(){ return this.f; }, 3. f: 1 4. }; 5. var f = foo.bar; 6. typeof f(); // ?
  • 153. this Exercise - solution What is the type of the value returned by f()? 1. var foo = { 2. bar: function(){ return this.f; }, 3. f: 1 4. }; 5. var f = foo.bar; 6. typeof f(); // "function"
  • 154. this Exercise What is the final result of this code? 1. var foo = { 2. bar: function(){ return this.foobar; }, 3. foobar: 1 4. }; 5. 6. typeof (xxx = foo.bar)(); // ?
  • 155. this Exercise - solution What is the final result of this code? 1. var foo = { 2. bar: function(){ return this.foobar; }, 3. foobar: 1 4. }; 5. 6. typeof (xxx = foo.bar)(); // "undefined"
  • 156. window
  • 157. window • window as a context 1. var fn = function() { 2. this.foobar = "foo"; 3. }; 4. 5. fn(); 6. foobar; // foo ! 1. var fn = function() { 2. this === window; // true 3. }; 4. 5. fn();
  • 158. window • window as a context 1. <script type="text/javascript"> 2. var fn = function() { 3. alert(window === this); // true 4. }; 5. fn(); 6. </script> 1. <script type="text/javascript"> 2. alert(window === this); // true 3. </script>
  • 159. window • window as a global object 1. <script type="text/javascript"> 2. var global = (function() { return this; })(); 3. window === global; // true 4. </script>
  • 160. window • curiosities 1. <script type="text/javascript"> 2. var x = "foobar" in window; // true 3. var foobar = 2; 4. </script> 1. <script type="text/javascript"> 2. alert(window['foobar']); // undefined 3. var foobar = 2; 4. alert(window['foobar']); // 2 5. </script>
  • 161. window is a browser global object!
  • 162. Functions are objects
  • 163. Functions are objects • basics 1. var fn = function() {}; 2. fn.foobar = "2"; 3. fn.foobar; // 2 1. var fn = function() {}; 2. fn.method = function() { return this === fn; }; 3. fn.method(); // true
  • 164. Functions are objects • basics 1. var fn = function() {}; 2. fn.method = function() { return "foobar"; } 3. var obj = new fn; 4. obj.method(); // error • why is an error here?
  • 165. Functions are objects • Function constructor 1. var fn = Function("return "foobar "foobar""); 2. fn(); // "foobar" 1. var fn = Function("return "foobar "foobar""); 2. typeof fn; // function 1. var fn = new Function("return "foobar "foobar""); 2. typeof fn; // function 1. var fn = new Function("return "foobar "foobar""); 2. fn.toString(); // "function anonymous() { return "foobar"; }" 1. var fn = Function("return "foobar "foobar""); 2. fn.constructor.toString(); 3. // "function Function() { [native code] }"
  • 166. Functions are objects • Function constructor and the prototype chain 1. var fn = Function("return "foobar "foobar""); 2. fn.__proto__.constructor; // Function [native] 3. fn.__proto__.__proto__.constructor; // Object [native] 1. var fn = function() { return "foobar" }; "foobar"; 2. fn.__proto__.constructor; // Function [native] 3. fn.__proto__.__proto__.constructor; // Object [native] 1. var fn = function() { return "foobar" }; "foobar"; 2. fn.__proto__.constructor; // Function [native] 3. fn.__proto__.__proto__.constructor; // Object [native] 4. fn.__proto__.__proto__.__proto__; // null
  • 167. Functions are objects • IE vs Firefox 1. if (true) { 2. function fn() {}; 3. } else { 4. function fn() { return 2; } 5. } 6. 7. alert(fn); 1. var fn = function some() {}; 2. alert(typeof fn);
  • 168. Functions are objects • anonymous functions 1. var fn = function(name, f) { 2. return { 3. name: name, 4. fn: f 5. }; 6. }; 7. 8. var multiple = fn("any function", function(x, y) { return x * y; }); 9. multiple.fn(2, 3); // 6
  • 169. Functions are objects • .call 1. var fn = function(a, b) { 2. return a * this + b; 3. }; 4. 5. fn.call(5, 1, 2);
  • 170. Functions are objects • .call 1. var fn = function(a, b) { 2. return a * this + b; 3. }; 4. 5. fn.call(5, 1, 2); // 7
  • 171. Functions are objects • .call 1. var fn = function() { 2. return this; 3. }; 4. 5. var obj = { foobar: "foobar" }; 6. obj === fn.call(obj);
  • 172. Functions are objects • .call 1. var fn = function() { 2. return this; 3. }; 4. 5. var obj = { foobar: "foobar" }; 6. obj === fn.call(obj); // true !
  • 173. Functions are objects • .apply 1. var fn = function(a, b, c) { 2. return a + b + c; 3. }; 4. fn.apply(this, [1, 2, 3]);
  • 174. Functions are objects • .apply 1. var fn = function(a, b, c) { 2. return a + b + c; 3. }; 4. fn.apply(this, [1, 2, 3]); // 6
  • 175. Functions are objects • .call and .apply – .call requires every single argument – .apply requires only the arguments array – .apply > .call? • usage: – callbacks – JAVA-like class abstractions – event handlers – many others
  • 176. .call Exercise What is the result of this code? 1. var fn = function() { 2. return this; 3. }; 4. fn.call(null); // ?
  • 177. .call Exercise What is the result of this code? 1. var fn = function() { 2. return this; 3. }; 4. fn.call(null); // window
  • 178. arguments
  • 179. 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" array like" 1. var fn = function(a, b, c) { 2. return arguments.length; 3. }; 4. fn(1, 2, 3); // 3
  • 180. Functions are objects • why is not arguments the proper array? 1. var fn = function(a) { 2. return arguments.constructor; // Object .constructor; 3. }; 1. var arr = []; 2. arr.constructor; // Array 1. var fn = function(a) { 2. return arguments.pop(); // error ! 3. };
  • 181. 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 helpful 1. var fn = function(a) { 2. arguments[0] = 5; 3. return a; 4. }; 5. 6. fn(2); // 5;
  • 182. Functions are objects • why useful? – handling unpredictable numbers of arguments 1. var add = function() { 2. for (var i = 0, l = arguments.length, sum = 0; i < l; i++) { 3. sum += arguments[i]; 4. } 5. }; 6. 7. add(2, 3, 4); // 9 – validating the number of arguments
  • 183. 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. };
  • 184. 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; 1. var fn = function(a, b) {}; 2. fn.length; // 2 3. fn.length = 4; 4. fn.length; // 2
  • 185. Functions are objects • fn.length – thinking about arguments number validation 1. var fn = function(a, b) { 2. if (arguments.length !== fn.length) { 3. throw new Error("This function requires at least two This arguments passed!"); 4. } 5. }; 6. 7. fn();
  • 186. Functions are objects Exercise Try to implement addMethod function, which would simulate method overloading 1. var obj = { 2. property: "foobar" 3. }; 4. 5. addMethod(obj, "methodName", function(a) { return a; }); 6. addMethod(obj, "methodName", function(a, b) { return a + b; }); 7. addMethod(obj, "methodName", function() { return 2; }); 8. 9. obj.methodName(1); // 1 10.obj.methodName(2, 3); // 5 11.obj.methodName(); // 2
  • 187. Anonymous recursion
  • 188. Anonymous recursion • arguments.callee 1. var factorial = function(x) { 2. if (x > 0) { 3. return x * arguments.callee(x arguments.callee(x-1); 4. } 5. return 1; 6. }; 7. 8. factorial(4); // 24 • deprecated in strict mode!
  • 189. Anonymous recursion • a bit different 1. var factorial = function factorial factorial(x) { 2. if (x > 0) { 3. return x * factorial(x (x-1); 4. } 5. return 1; 6. }; 7. 8. factorial(4); // 24
  • 190. Arrays
  • 191. Arrays • there is no "array" type 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...
  • 192. Arrays Exercise Try to implement a simple CustomMap constructor, which works like an associative array and has three methods: add(key, value), remove(key), getLength. 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"); // 1 8. colors.remove("blue"); 9. colors.getLength(); // 1
  • 193. Arrays • removing array elements – wrong approach 1. var arr = [1, 2, 3]; 2. delete arr[1]; // true 3. arr.length; // 3 • right approach 1. var arr = [1, 2, 3]; 2. arr.splice(1, 1); 3. arr.length; // 2 • .splice returns an array of the elements removed 1. var arr = [1, 2, 3]; 2. arr.splice(1, 1)[0]; // 2
  • 194. Arrays • cloning arrays – slice 1. var arr = [1, 2, 3]; 2. var newArr = arr.slice(0); – concat • .splice zwraca tablicę usuniętych 1. var arr = [1, 2, 3]; elementów 2. var newArr = [].concat(arr);
  • 195. Arrays • merging arrays – jQuery approach (merges either arrays or objects) 1. var i = first.length, j = 0; 2. if ( typeof second.length === "number" ) { 3. for ( var l = second.length; j < l; j++ ) { 4. – concat first[ i++ ] = second[ j ]; 5. .splice zwraca tablicę usuniętych elementów • } 6. } else { 7. while ( second[j] !== undefined ) { 8. first[ i++ ] = second[ j++ ]; 9. } 10.} 11. 12.first.length = i; 13.return first;
  • 196. Arrays • merging arrays – push 1. var arr = [1, 2, 3]; 2. arr.push.apply(arr, [3, 4, 5]); 3. arr; // [1, 2, 3, 3, 4, 5]
  • 197. Arrays • forEach – JavaScript 1.6 - Firefox 1. var arr = [1, 2, 3]; 2. arr.forEach(function(i) { 3. alert(i); 4. });
  • 198. Arrays Exercise Implement your own forEach method when it is not supported by the browser engine.
  • 199. Arrays Exercise - solution 1. if (!Array.prototype.forEach) { 2. Array.prototype.forEach = function(callback) { 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. }
  • 200. Arrays • max value inside the array 1. var arr = [1, 2, 3]; 2. Math.max.apply(Math, arr); // 3 • min value inside the array 1. var arr = [1, 2, 3]; 2. Math.min.apply(Math, arr); // 1
  • 201. Classical objects and classes approach
  • 202. JavaScript !== Java
  • 203. What things is JavaScript missing? • class keyword and similar ones • extends keyword • methods and operators overloading • public, protected, private accessors • static typing • abstraction classes, interfaces • and much more
  • 204. 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 my early attempts to support the classical model in JavaScript as a mistake. Douglas Crockford http://crockford.com
  • 205. Public properties • object literals 1. var obj = { 2. method: function() {}, 3. property: 1000 4. }; • constructors 1. var klass = function() { 2. this.method = function() {}; 3. this.property = 1000; 4. }; 5. var obj = new klass; 6. obj.property; 7. obj.method();
  • 206. Take care of prototypes!
  • 207. Public properties • constructor 1. var klass = function() { 2. this.property = 1000; 3. }; 4. 5. klass.prototype.method = function() {}; 6. 7. var obj = new klass; 8. obj.property; 9. obj.method();
  • 208. Reusable code!
  • 209. Private properties • object literals 1. var obj = (function() { 2. var priv = 200; 3. return { 4. method: function(){}, 5. method2: function() {}, 6. property: 1000 7. }; 8. })(); 9. obj.priv; // undefined
  • 210. Private properties • constructors 1. var klass = function() { 2. var priv = 200; 3. 4. this.method = function() {}; 5. this.property = 1000; 6. }; 7. 8. var obj = new klass; 9. obj.priv; // undefined
  • 211. Prototypal inheritance 1. var base = function() { 2. this.method = function() { return 100; }; 3. }; 4. 5. var child = function() { 6. this.method2 = function() { return 200; } 7. }; 8. 9. child.prototype = new base; ! 10. 11.var obj = new child; 12.obj.method(); // 100 13.obj instanceof base; // true
  • 212. Functional inheritance 1. var base = function() { 2. return { 3. method: function() { return 100; }; 4. }; 5. }; 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
  • 213. Class abstractions • mootools – http://mootools.net mootools.net 1. var Animal = new Class({ 2. initialize: function(age){ 3. this.age = age; 4. } 5. }); 6. var Cat = new Class({ 7. Extends: Animal, 8. initialize: function(name, age){ 9. this.parent(age); //will call initalize of Animal 10. this.name = name; 11. } 12.}); 13.var myCat = new Cat('Micia', 20); var 14.alert(myCat.name); // 'Micia' 15.alert(myCat.age); // 20
  • 214. Class abstractions • jQuery - http://code.google.com/p/jquery code.google.com/p/jquery-klass 1. Animal = $.klass({ 2. init: function( sound ) { 3. this.sound = sound; 4. }, 5. say: function( 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.});
  • 215. Namespacing • what are namespaces? • example usage 1. var com = {}; 2. com.testApp = {}; 3. 4. com.testApp.utils = { 5. trim: function() {} 6. }; 7. 8. com.testApp.utils.trim();
  • 216. Namespacing • single namespaces 1. var app = {}; 2. 3. app.options = { 4. foobar: "foo", 5. bar: "bar" 6. }; 7. app.events = {}; 8. etc... • risks • performance
  • 217. 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 (){ 8. return instance || (instance = new Constructor); 9. } 10. }; 11.})();
  • 218. What's about object literals!?
  • 219. Factory pattern in JavaScript • : 1. var Person = (function () { 2. var Person = function (name, location) { 3. this.name = name; 4. this.location = location; 5. }; 6. 7. return function (name, location) { 8. return new Person(name, location); 9. }; 10.})();
  • 220. bind()
  • 221. 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)); // ! 8. } 9. } 10. 11. var fn = function() { 12. alert(this); 13. }; 14. 15. fn = fn.bind("foobar"); 16. fn(); // "foobar"
  • 222. currying
  • 223. Currying : 1. Function.prototype.curry = function() { • 2. var fn = this; 3. var args = Array.prototype.slice.call(arguments); // ["bla bla"] 4. 5. return function() { 6. var args2 = Array.prototype.slice.call(arguments); // [2] 7. return fn.apply(this, args.concat(args2)); // ["bla bla", 2] 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
  • 224. chaining
  • 225. Chaining : 1. var chaining = (function() { • 2. return { 3. method1: function() { 4. alert("one"); 5. return this; // ! 6. }, 7. method2: function() { 8. alert("two"); 9. return this; // ! 10. } 11. }; 12. })(); 13. 14. chaining.method1().method2();
  • 226. Code optimization
  • 227. http://www.slideshare.net/ www.slideshare.net/ madrobby/extreme- madrobby/extreme javascript-performance performance
  • 228. Avoid functions calling
  • 229. Code optimization • : 1. while (i) { 2. fn(i); 3. var i = fn2(); 4. fn3(i); 5. };
  • 230. Use local variables!
  • 231. Code optimization • : 1. var fn = function() { 2. var events = library.utils.events; 3. var proxy = library.services.proxy; 4. };
  • 232. Avoid try{} catch() {}
  • 233. Take care of for loops
  • 234. 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--) {};
  • 235. Code optimization Exercise Write a function which multiplies every second array element by two.
  • 236. memoization – remember!
  • 237. 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)); // what 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. };
  • 238. yielding
  • 239. ~~(1 * "2.22") faster than parseInt("2.22")
  • 240. Simpler - faster
  • 241. Code optimization • slow 1. var min = Math.min(a, b); 2. arr.push(val); • fast 1. var min = a < b ? a : b; 2. arr[arr.length] = val;
  • 242. Thanks!
  • 243. Rafał Kukawski http://blog.kukawski.pl review, proofreading
  • 244. Lea Verou http://leaverou.me proofreading