Advertisement

JavaScript - From Birth To Closure

Global Lead for Programs & Initiatives, Web Developer Relations
Nov. 9, 2009
Advertisement

More Related Content

More from Robert Nyman(20)

Advertisement

Recently uploaded(20)

JavaScript - From Birth To Closure

  1. JavaScript From birth to closure
  2. Yeah, nothing
  3. Brendan Eich
  4. Brendan Eich
  5. What is JavaScript?
  6. • Developed by Brendan Eich 1995 • Initially called Mocha, then LiveScript • First day of light in a beta of Netscape 2 in December 1995 • IE followed suit with JScript in 1996
  7. “You’re number one!”
  8. Has NOTHING to do with Java!
  9. • JavaScript is one of the world’s most popular programming languages • One interpreter on every machine • ECMAScript standardizing - Fifth edition • Web browsers becoming much faster
  10. SunSpider test
  11. Douglas Crockford
  12. Douglas Crockford
  13. • JSON • JSLint • JSMin
  14. JavaScript basics
  15. Variable declaration: var benAffleck = ”Actor”;
  16. Function declaration: function benQuote () { ! return "Rumors about me? Calista Flockhart, Pam Anderson, and Matt Damon. That's who I'm dating."; }
  17. Conditionals
  18. • If • Switch • Shorthand assignment • Ternary operators
  19. function makeMovie (withLivTyler) { ! var nice = withLivTyler || false; }
  20. (datedJLo)? "Lucky guy!" : "No?";
  21. Comparison operators
  22. • = Assignment • == Equality • === Identity
  23. // Assignment var bestFriend = "Matt Damon"; // Equality if (5 == "5") { ! // true } // Identity if (5 === "5") { ! // false }
  24. // Short-circuit logic if (true || false) if (false && true) // Makes this code safe if (obj && obj.property)
  25. // Short-circuit logic if (true || false) if (false && true) // Makes this code safe if (obj && obj.property)
  26. Type coercion
  27. // true 5 == "5" // 123 "1" + 2 + 3;
  28. // 6, manual type conversion parseInt("1", 10) + 2 + 3;
  29. null == undefined == 0 == false == "" • Not really, but sort of • Rather “truthy” or “falsy”
  30. var a = null; var b; // undefined var c = 0; var d = false; var e = ""; if (a) // false if (b) // false if (c) // false if (d) // false if (e) // false
  31. JavaScript data types
  32. • string • number • boolean • null • undefined • Object
  33. Types of Object include: • function • Array • Date • RegExp
  34. Checking type
  35. typeof return values: • string • number • boolean • function • object • undefined
  36. typeof fanClub // "undefined" var title = "Armageddon"; typeof title // Equals "string" var age = 37; typeof age // Equals "number"
  37. function anotherQuote () { ! return "If I ever woke up with a dead hooker in my hotel room, Matt would be the first person I'd call."; } typeof anotherQuote; //"function"
  38. var obj = {}; typeof obj = // "object" var arr = ["B", "E", "N"]; typeof arr // "object"
  39. var obj = {}; typeof obj = // "object" var arr = ["B", "E", "N"]; typeof arr // "object" ?!
  40. Using instanceof
  41. obj instanceof Array // false arr instanceof Array // true
  42. Functions
  43. Procedural function notAHit () { ! return "Gigli"; }
  44. Functions as variables var wroteScript = function () { ! return "Good Will Hunting"; }; wroteScript();
  45. Anonymous document.onmousemove = function (evt) { alert(evt.pageX); };
  46. Self-invoking (function () { ! var dogma = "Shot in 1999"; })();
  47. Self-invoking (function () { ! var dogma = "Shot in 1999"; })();
  48. Function arguments
  49. • Any argument can be omitted • Any argument can be added • No overloading • The arguments collection
  50. function concat (a, b, c) { ! return a + b + c; } concat(1, 2, 3); // 6 concat(1, 2); // NaN
  51. • The arguments collection • Property: arguments.length • NOT an array
  52. function concat () { ! var sum = 0, l = arguments.length; ! for (var i=0; i<l; i++) { ! ! sum += arguments[i]; ! } ! return sum; } concat(1, 2, 3); // 6 concat(1, 2); // 3 concat(1, 2, 7, 11, 5); // 26
  53. Objects
  54. function Ben () { ! this.name = "Ben Affleck"; ! this.gotAnOscar = true; }; var ben = new Ben(); alert(ben.gotAnOscar); // true Object constructor
  55. var ben = { ! name : "Ben Affleck", ! gotAnOscar : true }; alert(ben.name); // "Ben Affleck" Object literal
  56. Different syntax, same thing: ben["arms"] = 2; ben.arms = 2;
  57. Different syntax, same thing: ben["arms"] = 2; ben.arms = 2;
  58. For any object: var ben = {}; ben[1972] = "Year of birth"; ben["born"] = 1972; ben[true] = false;
  59. var regEx = new RegExp; regEx[3] = "I can do this?";
  60. var goodMovie = { ! title : "Good Will Hunting", ! year : 1997 }; for (var item in goodMovie) { ! alert(item + ": " + goodMovie[item]); }
  61. var goodMovie = { ! title : "Good Will Hunting", ! year : 1997 }; // Check returns true if ("year" in goodMovie) { ! alert(goodMovie.year); }
  62. Inheritance
  63. • Prototype-based inheritance • Not class-based
  64. • The prototype chain checks itself first • It then goes to the parent, parent’s parent etc...
  65. function Being () { ! this.living = true; } Being.prototype.greet = function () { ! return "Hello!"; };
  66. function Ben () { ! this.talks = true; } Ben.prototype = new Being; Ben.prototype.saySomething = function () { ! return "I feel like fame is wasted on me."; };
  67. // Create an instance var ben = new Ben(); // Returns "I feel like fame is wasted on me." ben.saySomething(); // Returns "Hello!", inherited // from the Being object ben.greet();
  68. Checking for the greet() method in this order: • ben instance • Ben prototype • Being prototype • Object prototype
  69. • Simple JavaScript Inheritance • A Base Class for JavaScript Inheritance • Defining classes and inheritance Class-based mimicking
  70. • It’s native, i.e. no dependencies • Freedom of style and version • Easy readability • Code handover Why prototype syntax
  71. “I have been writing JavaScript for 8 years now, and I have never once found need to use an uber function... ...I now see my early attempts to support the classical model in JavaScript as a mistake.” - Douglas Crockford Why prototype syntax
  72. Scope
  73. • Scope refers to where variables and functions are accessible • In what context something is being executed
  74. • Basically, global or local • Variables have function scope • Functions have the same scope as variables
  75. // Global var likesToPlay = "Poker"; function getGame () { ! // Local ! var likesToPlay = "Hold ‘em"; ! // Global ! playOnline = true; ! return likesToPlay; ! // Returns "Hold ‘em" }
  76. function playPoker (money) { ! if (money) { ! ! var willPlay = true; ! } ! // Perfectly valid ! return willPlay; }
  77. function global () { ! return "Access anywhere"; }
  78. function outer () { ! function inner () { ! ! return "Inner"; ! } ! return inner(); } outer(); // Accessible inner(); // Not accessible
  79. “Global scope is like a public toilet. You can’t avoid going in there. But try to limit your contact with surfaces when you do.” - Dmitry Baranovskiy, Raphaël JS library Polluting the global namespace
  80. Function scope
  81. • Run a function in a certain context • The call and apply methods • Defined for all functions
  82. function docReady () { ! alert(this); ! // this is the window object } window.onload = docReady;
  83. function setName (name) { ! this.name = name; ! // document.name === "Bennifer" } document.onclick = function () { ! setName.call(document, "Bennifer"); };
  84. function setName (name) { ! this.name = name; ! // document.name === "Bennifer" } document.onclick = function () { ! setName.call(document, "Bennifer"); };
  85. function setNames () { ! this.firstName = arguments[0]; ! this.lastName = arguments[1]; // document.firstName === “Ben” // document.lastName === “Affleck” } function callSetNames () { ! setNames.apply(document, arguments); }; callSetNames("Ben", "Affleck");
  86. function setNames () { ! this.firstName = arguments[0]; ! this.lastName = arguments[1]; // document.firstName === “Ben” // document.lastName === “Affleck” } function callSetNames () { ! setNames.apply(document, arguments); }; callSetNames("Ben", "Affleck");
  87. Closures
  88. • Closures are expressions, usually functions, which can work with variables set within a certain context • Inner functions referring to local variables of its outer function create closures
  89. function add (x) { ! return function (y) { ! ! return x + y; ! }; } var add5 = add(5); var no7 = add5(2); // Equals 7
  90. “Right...What?!”
  91. function add (x) { ! return function (y) { ! ! return x + y; ! }; } var add5 = add(5); // How JavaScript sees it var add5 = function (y) { ! return 5 + y; }
  92. function add (x) { ! return function (y) { ! ! return x + y; ! }; } var add5 = add(5); // How JavaScript sees it var add5 = function (y) { ! return 5 + y; }
  93. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function () { ! ! ! alert(i); ! ! }; ! ! document.body.appendChild(link); ! } } window.onload = addLinks;
  94. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function () { ! ! ! alert(i); ! ! }; ! ! document.body.appendChild(link); ! } } window.onload = addLinks; ! ! link.onclick = function () { ! ! ! alert(i); ! ! };
  95. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i); ! ! document.body.appendChild(link); ! } } window.onload = addLinks;
  96. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i); ! ! document.body.appendChild(link); ! } } window.onload = addLinks; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i);
  97. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i); ! ! document.body.appendChild(link); ! } } window.onload = addLinks; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i);
  98. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i); ! ! document.body.appendChild(link); ! } } window.onload = addLinks; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i);
  99. function addLinks () { ! for (var i=0, link; i<5; i++) { ! ! link = document.createElement("a"); ! ! link.innerHTML = "Link " + i; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i); ! ! document.body.appendChild(link); ! } } window.onload = addLinks; ! ! link.onclick = function (num) { ! ! ! return function () { ! ! ! ! alert(num); ! ! ! }; ! ! }(i);
  100. Yahoo JavaScript Module Pattern
  101. • Origins from Douglas Crockford • Singleton pattern • Offers private and public members
  102. var goneBabyGone = function () { ! // Private members ! var movieTitle = "Gone Baby Gone", isDirectedByBen = true; ! ! // Public members ! return { ! ! title : function () { ! ! ! return movieTitle; ! ! }, ! ! ! ! directedByBen : function () { ! ! ! return isDirectedByBen; ! ! } ! }; }();
  103. var goneBabyGone = function () { ! // Private members ! var movieTitle = "Gone Baby Gone", isDirectedByBen = true; ! ! // Public members ! return { ! ! title : function () { ! ! ! return movieTitle; ! ! }, ! ! ! ! directedByBen : function () { ! ! ! return isDirectedByBen; ! ! } ! }; }();
  104. var goneBabyGone = function () { ! // Private members ! var movieTitle = "Gone Baby Gone", isDirectedByBen = true; ! ! // Public members ! return { ! ! title : function () { ! ! ! return movieTitle; ! ! }, ! ! ! ! directedByBen : function () { ! ! ! return isDirectedByBen; ! ! } ! }; }();
  105. var goneBabyGone = function () { ! // Private members ! var movieTitle = "Gone Baby Gone", isDirectedByBen = true, ! ! title = function () { ! ! ! return movieTitle; ! ! }, ! ! ! ! directedByBen = function () { ! ! ! return isDirectedByBen; ! ! }; ! ! // Public members ! return { title : title, directedByBen : directedByBen ! }; }();
  106. Namespacing
  107. • Avoiding global variables • Code structure • Extending, but not necessarily inheriting
  108. // Create a Ben object var Ben = {}; // Set functionality Ben.Director = function () { ! var noOfMovies = 4; ! return { ! ! movies : function () { ! ! ! return noOfMovies; ! ! } ! }; }();
  109. // Assertion if (typeof Ben === "undefined") { ! Ben = {}; } Ben.Actor = function () { ! var noOfMovies = 51; ! return { ! ! actAndDirectorCount : function () { ! ! ! return noOfMovies + " as actor & " + Ben.Director.movies.call(this) + " as Director"; ! ! } ! }; }();
  110. Sugar & spice It’s awfully nice!
  111. • Sugaring • Currying
  112. // A little sugar String.prototype.trim = function () { ! return this.replace(/^s*|s*$/g, ""); }; var monkey = " Monkey "; monkey.trim(); //"Monkey"
  113. // Currying function add () { ! var sum = 0; ! for (var i=0, il=arguments.length; i<il; i++) { ! ! sum += arguments[i]; ! }; ! return sum; }
  114. // Currying (continued) - Currying method by Crockford! ! Function.prototype.curry = function () { ! var slice = Array.prototype.slice, ! ! args = slice.apply(arguments), ! ! that = this; ! return function () { ! ! ! return that.apply( ! ! ! ! null, args.concat(slice.apply(arguments)) ! ! ! ); ! }; } var add8 = add.curry(5, 3); alert(add8(1, 3, 7)); // 19
  115. // Currying (continued) - Currying method by Crockford! ! Function.prototype.curry = function () { ! var slice = Array.prototype.slice, ! ! args = slice.apply(arguments), ! ! that = this; ! return function () { ! ! ! return that.apply( ! ! ! ! null, args.concat(slice.apply(arguments)) ! ! ! ); ! }; } var add8 = add.curry(5, 3); alert(add8(1, 3, 7)); // 19
  116. // Currying (continued) - Currying method by Crockford! ! Function.prototype.curry = function () { ! var slice = Array.prototype.slice, ! ! args = slice.apply(arguments), ! ! that = this; ! return function () { ! ! ! return that.apply( ! ! ! ! null, args.concat(slice.apply(arguments)) ! ! ! ); ! }; } var add8 = add.curry(5, 3); alert(add8(1, 3, 7)); // 19
  117. // Currying (continued) - Currying method by Crockford! ! Function.prototype.curry = function () { ! var slice = Array.prototype.slice, ! ! args = slice.apply(arguments), ! ! that = this; ! return function () { ! ! ! return that.apply( ! ! ! ! null, args.concat(slice.apply(arguments)) ! ! ! ); ! }; } var add8 = add.curry(5, 3); alert(add8(1, 3, 7)); // 19
  118. // Currying (continued) - Currying method by Crockford! ! Function.prototype.curry = function () { ! var slice = Array.prototype.slice, ! ! args = slice.apply(arguments), ! ! that = this; ! return function () { ! ! ! return that.apply( ! ! ! ! null, args.concat(slice.apply(arguments)) ! ! ! ); ! }; } var add8 = add.curry(5, 3); alert(add8(1, 3, 7)); // 19
  119. // Currying (continued) - Currying method by Crockford! ! Function.prototype.curry = function () { ! var slice = Array.prototype.slice, ! ! args = slice.apply(arguments), ! ! that = this; ! return function () { ! ! ! return that.apply( ! ! ! ! null, args.concat(slice.apply(arguments)) ! ! ! ); ! }; } var add8 = add.curry(5, 3); alert(add8(1, 3, 7)); // 19
  120. Syntax recommendations
  121. • No real standard, only best practices • Recommended tool: JSLint
  122. Embrace JavaScript
  123. • Embrace JavaScript • Don’t try to make it into Java, C or any other language • Learn to love it and its dynamic, loose and prototypical nature
  124. This is how we roll
  125. Robert Nyman robertnyman.com/speaking/ robert@robertnyman.com Twitter: @robertnyman Pictures: Brendan - http://www.flickr.com/photos/mollyeh11/279367481/ Yoda - http://buzzybeegirl.files.wordpress.com/2008/12/yoda-400x3001.jpg Twitter - http://twitter.com/manssandstrom/status/1528315581 Gmail - http://www.flickr.com/photos/webber/71748774/ Slow - http://www.feministing.com/archives/012345.html Crockford - http://www.flickr.com/photos/charliebrewer/2897862701/ Obi-Wan - http://enterthecircle.files.wordpress.com/2009/01/obi-wan-kenobi-01-large.jpg Ben Affleck - http://www.flickr.com/photos/sasy/3993866442/ Squat toilet - http://www.flickr.com/photos/35034350906@N01/4080372999 Cuddling bears - http://www.nogg.se/blogg.asp?intShowMenu=a2&idHomepage=6951&idBloggCategory=6162 Winnie The Pooh and friends - http://mammacarola.blogg.se/2009/april/ IEVoodoo Doll - http://nexus404.com/Blog/2007/10/26/make-your-own-internet-explorer-voodoo-doll-a-step-by-step-guide/ Ben Affleck confused - http://cdn.buzznet.com/assets/imgx/4/9/0/5/8/orig-49058.jpg
Advertisement