300 likes | 439 Views
JavaScript Enlightenment. Johnathan Hebert. Agenda. Introductions Presentation Brief history of JavaScript Objects in depth Functions in depth A few tricks Questions. It is (finally) getting better. Invented by Brendan Eich @ Netscape in 1995 Standardized by Ecma in 1997 (Ecma-262)
E N D
JavaScript Enlightenment Johnathan Hebert
Agenda • Introductions • Presentation • Brief history of JavaScript • Objects in depth • Functions in depth • A few tricks • Questions
It is (finally) getting better • Invented by Brendan Eich @ Netscape in 1995 • Standardized by Ecma in 1997 (Ecma-262) • 3rd Edition standardized in Dec 1999 • Untouched for 10 years, this is the one you know • 4th Edition was abandoned • Vendor disagreements • 5th Edition standardized in Dec 2009 • Bug fixes, enhanced built-in objects, but no new syntax • Shipped in Chrome, Firefox, Safari, Opera and IE9+ • 5.1 Edition standardized in Jun 2011 • Fixes errata in 5th Edition, identical in content to 5th Edition • ES.next AKA Harmony (6th) Edition is well on its way… • Lots of new stuff
JavaScript Enlightenment • JavaScript book by Cody Lindley • http://www.javascriptenlightenment.com/ • Summary of ECMA-262 3rd edition • http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf
What's in the book? "It was my intention to write a book to give the reader an accurate JavaScript worldview through an examination of native JavaScript objects and supporting nuances: complex values, primitive values, scope, inheritance, the head object, etc. I intend this book to be a short and digestible summary of the ECMA-262, Edition 3 specification, focused on the nature of objects in JavaScript." - Cody Lindley
Everything is (acts like) an object // JavaScript only has 6 types var pet = {name:'george'}, // Object type = 'monkey', // String age = 5.0, // Number curious = true, // Boolean nothing = null, // Null missing = undefined; // Undefined // what about Function, Array, Date, RegExp, etc? // they are all just objects... console.log(typeofArray.prototype); // "object"
Is "function" a JavaScript type? // functions are objects that implement [[call]] -- // see prescribed algorithm for the typeof operator:
The [[prototype]] hidden property // a hidden [[prototype]] property is created // automatically and points to the prototype of the // constructor function var pet = { name:'george', type:'monkey', description:'curious' }; Object. prototype pet
Prototype link is fixed // objects do not have a property named prototype, // they have a hidden property called [[prototype]] console.log(pet.prototype) // undefined // access it through the constructor property varpetProto = pet.constructor.prototype; // you can add a property named prototype, but it // does not change the hidden [[prototype]] link pet.prototype = {type:'animal'};
How does the prototype get there? // the hidden prototype link is fixed at the object // construction step – these are the same: var pet = {}; var pet = new Object(); // the pet object is constructed with the Object() // constructor function, which does a few things: 1. a new empty object is created in memory 2. the object gets a hidden link to Object.prototype 3. the this keyword in the Object() function points to the new empty object 4. Object() function code is executed
Prescribed construct algorithm // see prescribed algorithm for object construction:
What does this really do? function Animal() { this.type = 'animal'; } var pet = new Animal();
Built-in Object Relationships Object.prototype {} Object () Function.prototype () [[prototype]] Function () prototype
Define a New Constructor Function function Animal() { this.type = 'animal'; } Object.prototype {} Object () Function.prototype () [[prototype]] Function () prototype
Define a New Constructor Function function Animal() { this.type = 'animal'; } Object.prototype {} Animal.prototype {} Object () Function.prototype () Animal () [[prototype]] Function () prototype constructor
Create a New Object Object.prototype {} Animal.prototype {} Object () pet {} Function.prototype () Animal () [[prototype]] var pet = new Animal(); Function () prototype constructor
Object inheritance using prototypes // create a named function via a function statement function Animal() { this.type = 'animal'; } // Animal automatically gets a prototype property console.log(typeofAnimal.prototype) // 'object' // pet will have a hidden link to Animal.prototype var pet = new Animal(); Animal. Prototype pet {type:'animal'} Object. prototype
Functions can be constructors // the this keyword refers to the new object function Animal() { this.type = 'animal'; }; // any function can be invoked with the new keyword // to be a constructor (invokes [[construct]]) var pet = new Animal(); console.log(pet.type); // 'animal' // No object is created without the new keyword // WARNING: this now references global object var pet = Animal(); // pet is undefined
Constructor function inheritance // will be used as the base constructor function function Animal() { this.type = 'animal'; }; // eventually inherit from the base constructor function function Monkey() { this.likesBananas = true; } // the magic happens here (inheritance) Monkey.prototype = new Animal(); // pet.type will refer to Animal.prototype.type var pet = new Monkey(); // pet Monkey.prototype Animal.prototype Object.prototype
Something is wrong! // why does this log Animal? why not Monkey? console.log(pet.constructor); // the orginalMonkey.prototype was overwritten Monkey.prototype = new Animal(); // culprit // the old Monkey.prototype had a property named // constructor – put it back: Monkey.prototype.constructor = Monkey; // fixed
Neat stuff with functions // start with the original constructor function function Animal() { this.type = 'animal'; }; // make the this keyword refer to another object varjohnathan = {type:'person'}; // random object console.log(johnathan.type); // 'person' Animal.call(johnathan); // this === johnathan console.log(johnathan.type); // 'animal'
Immediate execution of functions // evaluate a function statement as an expression (function sayHello(name) { alert('Hello ' + (name || 'nobody')); })('George'); // another way to evaluate as an expression !function() { alert('hi'); }(); // parens not necessary for function expressions var result = function sayHello(name) { alert('Hello ' + (name || 'nobody')); }('George');
Function closures // one function returns another function vargetSecret = function() { // private var var secret = 'JavaScript has private vars'; // this function is closed over outer vars return function() { return secret; }; }(); // secret is visible to the inner function after // the outer function has returned console.log(secret); // undefined console.log(getSecret()); // in the circle of trust
Anonymous function tricks // anonymous functions can call themselves // (won't work in ECMAScript 5+ strict mode) (function(i) { console.log(++i); if (i < 10) { arguments.callee(i); } })(0); // anonymous functions can be constructors too var anon = new function() {this.strange = true;}(); console.log(anon.strange); // true
Functions can have properties // count the number of times a function was called function sayHello(name) { console.log('Hello ' + (name || 'nobody')); arguments.callee.numCalls++; } sayHello.numCalls = 0; // call the function a couple of times sayHello('Curious George'); sayHello('Man in the yellow hat'); // numCalls is like a static property console.log(sayHello.numCalls); // 2
Why is this stuff important? // understand the libraries you are using (function( window, undefined ) { ... // the entire jQuery library })(window); // you might need it outside the browser (soon) var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); }).listen(1337, "127.0.0.1");
Summary • Everything in JavaScript is (acts like) an object • Objects have hidden links to a [[prototype]] • Functions are just "callable objects" • Be careful with semantics • Functions have a hidden [[prototype]] property • Functions also have a visible prototype property • Pay close attention to scoping • Lexical scoping by default • Scope chain can be modified at runtime