JavaScript - From Birth To Closure
-
Upload
robert-nyman -
Category
Technology
-
view
20.583 -
download
1
description
Transcript of JavaScript - From Birth To Closure
• 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
• 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
SunSpider test
• JSON
• JSLint
• JSMin
Function declaration:
function benQuote () {! return "Rumors about me?
Calista Flockhart, Pam Anderson, and Matt Damon. That's who I'm dating.";
}
// Assignmentvar bestFriend = "Matt Damon";
// Equalityif (5 == "5") {!// true}
// Identityif (5 === "5") {!// false}
// Short-circuit logicif (true || false)
if (false && true)
// Makes this code safeif (obj && obj.property)
// Short-circuit logicif (true || false)
if (false && true)
// Makes this code safeif (obj && obj.property)
var a = null;var b; // undefinedvar c = 0;var d = false;var e = "";
if (a) // falseif (b) // falseif (c) // falseif (d) // falseif (e) // false
typeof fanClub // "undefined"
var title = "Armageddon";
typeof title // Equals "string"
var age = 37;
typeof age // Equals "number"
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"
• Any argument can be omitted
• Any argument can be added
• No overloading
• The arguments collection
function concat () {! var sum = 0,
l = arguments.length;! for (var i=0; i<l; i++) {! ! sum += arguments[i];! }! return sum;}concat(1, 2, 3); // 6concat(1, 2); // 3concat(1, 2, 7, 11, 5); // 26
function Ben () {! this.name = "Ben Affleck";! this.gotAnOscar = true;};
var ben = new Ben();alert(ben.gotAnOscar); // true
Object constructor
var ben = {! name : "Ben Affleck",! gotAnOscar : true};
alert(ben.name); // "Ben Affleck"
Object literal
var goodMovie = {! title : "Good Will Hunting",! year : 1997};
for (var item in goodMovie) {! alert(item + ": " + goodMovie[item]);}
var goodMovie = {! title : "Good Will Hunting",! year : 1997};
// Check returns trueif ("year" in goodMovie) {! alert(goodMovie.year);}
function Ben () {
! this.talks = true;
}
Ben.prototype = new Being;
Ben.prototype.saySomething = function () {
! return "I feel like fame is wasted on me.";
};
// 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();
Checking for the greet() method in this order:
• ben instance
• Ben prototype
• Being prototype
• Object prototype
• Simple JavaScript Inheritance
• A Base Class for JavaScript Inheritance
• Defining classes and inheritance
Class-based mimicking
• It’s native, i.e. no dependencies
• Freedom of style and version
• Easy readability
• Code handover
Why prototype syntax
“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
• Scope refers to where variables and functions are accessible
• In what context something is being executed
• Basically, global or local
• Variables have function scope
• Functions have the same scope as variables
// Globalvar likesToPlay = "Poker";
function getGame () {! // Local! var likesToPlay = "Hold ‘em";
! // Global! playOnline = true;
! return likesToPlay;! // Returns "Hold ‘em"}
function playPoker (money) {! if (money) {! ! var willPlay = true;! }
! // Perfectly valid! return willPlay;}
function outer () {! function inner () {! ! return "Inner";! }! return inner();}outer(); // Accessibleinner(); // Not accessible
“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
function setName (name) {! this.name = name;! // document.name === "Bennifer"}
document.onclick = function () {! setName.call(document, "Bennifer");};
function setName (name) {! this.name = name;! // document.name === "Bennifer"}
document.onclick = function () {! setName.call(document, "Bennifer");};
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");
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");
• 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
function add (x) {! return function (y) {! ! return x + y;! };}var add5 = add(5);var no7 = add5(2); // Equals 7
function add (x) {! return function (y) {! ! return x + y;! };}var add5 = add(5);
// How JavaScript sees itvar add5 = function (y) {! return 5 + y;}
function add (x) {! return function (y) {! ! return x + y;! };}var add5 = add(5);
// How JavaScript sees itvar add5 = function (y) {! return 5 + y;}
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;
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);
! ! };
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;
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);
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);
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);
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);
var goneBabyGone = function () {
! // Private members
! var movieTitle = "Gone Baby Gone",
isDirectedByBen = true;
!
! // Public members
! return {
! ! title : function () {
! ! ! return movieTitle;
! ! },
! !
! ! directedByBen : function () {
! ! ! return isDirectedByBen;
! ! }
! };
}();
var goneBabyGone = function () {
! // Private members
! var movieTitle = "Gone Baby Gone",
isDirectedByBen = true;
!
! // Public members
! return {
! ! title : function () {
! ! ! return movieTitle;
! ! },
! !
! ! directedByBen : function () {
! ! ! return isDirectedByBen;
! ! }
! };
}();
var goneBabyGone = function () {
! // Private members
! var movieTitle = "Gone Baby Gone",
isDirectedByBen = true;
!
! // Public members
! return {
! ! title : function () {
! ! ! return movieTitle;
! ! },
! !
! ! directedByBen : function () {
! ! ! return isDirectedByBen;
! ! }
! };
}();
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
! };
}();
// Create a Ben object
var Ben = {};
// Set functionality
Ben.Director = function () {
! var noOfMovies = 4;
! return {
! ! movies : function () {
! ! ! return noOfMovies;
! ! }
! };
}();
// 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";
! ! }
! };
}();
// A little sugar
String.prototype.trim = function () {
! return this.replace(/^\s*|\s*$/g, "");
};
var monkey = " Monkey ";
monkey.trim(); //"Monkey"
// Currying
function add () {
! var sum = 0;
! for (var i=0, il=arguments.length; i<il; i++) {
! ! sum += arguments[i];
! };
! return sum;
}
// 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
// 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
// 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
// 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
// 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
// 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
• No real standard, only best practices
• Recommended tool: JSLint
• 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
Robert Nymanrobertnyman.com/speaking/[email protected]
Twitter: @robertnyman
Pictures:Brendan - http://www.flickr.com/photos/mollyeh11/279367481/Yoda - http://buzzybeegirl.files.wordpress.com/2008/12/yoda-400x3001.jpgTwitter - http://twitter.com/manssandstrom/status/1528315581Gmail - http://www.flickr.com/photos/webber/71748774/Slow - http://www.feministing.com/archives/012345.htmlCrockford - http://www.flickr.com/photos/charliebrewer/2897862701/Obi-Wan - http://enterthecircle.files.wordpress.com/2009/01/obi-wan-kenobi-01-large.jpgBen Affleck - http://www.flickr.com/photos/sasy/3993866442/Squat toilet - http://www.flickr.com/photos/35034350906@N01/4080372999Cuddling bears - http://www.nogg.se/blogg.asp?intShowMenu=a2&idHomepage=6951&idBloggCategory=6162Winnie The Pooh and friends - http://mammacarola.blogg.se/2009/april/IE Voodoo 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