Preface

Mozilla javascript reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript

David Flanagan: O'Reilly JavaScript: The Definitive Guide http://shop.oreilly.com/product/9780596805531.do

Chapter 1: JavaScript Objects

Creating objects

An object in JavaScript is just a container for properties, each of which has a name and a value. Methods are just properties which contain a Function() object.

New objects can be created by calling the new Object() constructor function. User defined contructor functions can also be defined to create custom objects:

var Person = function (living, age, gender) {
    this.living = living;
    this.age = age;
    this.gender = gender;
this.getGender = function () { return this.gender; }; };

Conventionally, a capital letter is used (i.e. var Person, not var person).

Objects created from either new Person() or new Object() with the same properties will be exactly the same object. Only the method of creating is different.

Functions can be named or not named:

var Person = function (living, age, gender) { ... };
var Person = function Person (living, age, gender) { ... };

JavaScript constructors create and return object instances

A constructor function is a cookie cutter for producing objects that have default properties and property methods. The only difference between a constructor function and a normal function is how it behaves when invoked with the new keyword. In this case, JavaScript sets the value of this to the new object being created and returns it (instead of false).

The native JavaScript object constructors

Number(), String(), Boolean(), Object(), Array(), Function(), Date(), RegExp(), Error()

JavaScript is mostly constructed from these nine native (aka global) objects as well as the string, number and Boolean primitive values.

Note, Math is a static object, a container for methods (and therefore not instantiated using the new keyword).

Instantiating constructors using the new operator

Constructor functions can be called with or without the new keyword.

If called without using new:

  • the this referred to in a constructor function is no longer the object under construction, but the parent object (see Chapter 6)
  • the object is not returned (the constructor function could always explicity return the object)

You can log myobj.constructor to see the function definition (which for the built in types won't show you the actual defnition, but for an unknown type, will at least reveal how it was created and therefore reveal its type).

Creating shorthand or literal values from constructors

Literals are shorthand for creating objects for the built in types rather than calling the new keyword.

  • Number - just use the number
  • String - use quotes
  • Boolean - true or false
  • Object - {}
  • Array - []
  • Function - function(x, y) { return x* y };
  • RegExp - //

In general the effect is exactly the same as using the new keyword. However, in the case of number, string and boolean types, a complex object is not created until object properties are used. e.g 'foo'.length. Only at this point does a wrapper object get created and then discarded again afterwards.

Primitive (aka simple) values

The JavaScript values 5, 'foo', true, and false , as well as null and undefined, are considered primitive because they are irreducible.

Note, if using the new keyword to create String, Number or Boolean types, then complex objects are created and returned.

Note, if you alternatively call the String(), Number() or Boolean() constructor functions without the new keyword, the primitive values are returned. In this instance, are the complex objects constructed or not - I assume not.

Primitive values are stored and copied by value, and are equal if equal in value.

Complex objects (aka composite objects or reference types)

Complex values are stored and manipulated by reference. They are equal only if referring to the same reference (address).

The typeof operator used on primitive and complex values

declaration | primitive / complex | typeof x | x.constructor | beware ---|---|--- var x = null | primitive | object | [error] | * typeof x is object (not null) var x = undefined | primitive | undefined | [error] var x = "string" | primitive | string | String var x = String("string") | primitive | string | String var x = 23 | primitive | number | Number var x = Number(23) | primitive | number | Number var x = true | primitive | boolean | Boolean var x = Boolean(true) | primitive | boolean | Boolean var x = new Number(23) | complex | object | Number var x = new String("string") | complex | object | String var x = new Boolean(false) | complex | object | Boolean var x = new Object() | complex | object | Object var x = new Array("foo", "bar") | complex | object | Array var x = new Function("x", "y", "return x * y") | complex | function | Function | * typeof x is function (not object) var x = new Date() | complex | object | Date var x = new RegExp("[a-z]+") | complex | object | RegExp var x = new Error("Darn!") | complex | object | Error

Dynamic properties allow for mutable objects

User-defined objects and most of the native objects can be augmented with extra functionality, storing extra properties and adding new methods.

String.someExtraProperties = []; // add an array of extra properties
String.prototype.anExtraMethod = function() { // some extra method definition }; // add an extra function

All constructor instances have constructor properties that point to their constructor function

When any object is instantiated, the constructor property is created behind the scenes as a property of that object or instance. This property points to the constructor function that created the object.

This is useful for determining the type of an object (more useful than typeof for object types, see table above). Note that the value returned is a reference the constructor function, NOT a string containing the function's name.

User defined contructor functions work in exactly the same way and when logged will show the actual implementation details.

The instanceof function

By using the instanceof operator, we can determine (true or false) if an object is an instance of a particular constructor function.

var Person = function () { this.foo = 'bar'; };
var person = new Person();

console.log(person instanceof Person); // logs true
console.log(person instanceof Object); // logs true

// native objects work the same
console.log(new Array('foo') instanceof Array) // logs true
console.log(new Array('foo') instanceof Object); // logs true

Note, since all objects inherit from the Object() constructor all will return true for instanceof Object

Note, primitive values will return false from instanceof operations.

Instances can have their own properties

Objects can be augmented at any time (i.e. dynamic properties).

var myString = new String("hello");
myString.isGreeting = true;

Chapter 2: Working with Objects and Properties

  • Objects can be nested inside other objects (and functions, regexs etc) ad infinitum. Sometimes known as object chaining.
  • Get or set an object's properties using dot notation or brackets. Dot notation is more common, but bracket notation is useful when you have a variable containing the key or with property names which are invalid JavaScript identifiers (e.g. containing a numeral)
  • By using bracket notation you can mimic associative arrays found in other languages
  • If a property is a method, this can be invoked using the () operators e.g. cody.getGender()
  • The delete operator can be used to remove a property from an object e.g. delete person.name. Note, this will not delete properties found on the prototype chain.

How references to object properties are resolved

If you try to access a property not on the object, JavaScript will check on the prototype chain before returning undefined. E.g. accessing a non existent property on an Array object will also check Array.prototype and Object.prototype.

The prototype chain is built using the object contructor function's prototype object. This is the secret __proto__ link contained in all objects which points to the constructor function which created the instance, specifically, the prototype property of the instance’s constructor function.

For example, when you create a instance of an array, the join method is not a function on that particular instance, but via the __proto__ link, it can access the join method of the Array class.

var ar = new Array();
console.log(ar.hasOwnProperty('join')); // logs false
console.log(ar.__proto__.hasOwnProperty('join')); // logs true
console.log(ar.constructor.prototype.hasOwnProperty('join')); // logs true 
console.log(Array.prototype.hasOwnProperty('join')); // logs true

Note, use hasOwnProperty to check for properties specific to that object and not from the prototype change. in also appears to have this behaviour in chrome (contrary to the book's explanations that in includes all members of an object via the prototype chain).

Host objects and native objects

Within a browser environment, there are typically additional host objects which are not part of JavaScript specification, but just objects provided by the environment itself. These are in themselves very useful e.g. window and the objects it contains, but then are not part of the JavaScript specification.

Enumerate x in window to show all properties in the window host object of a browser.

Enumerate x in window.document to show all properties in the HTML document, or DOM.

Underscore.js

This library of functions extends the current offering of JavaScript 1.5 with a number of useful functions for all objects and a number more for arrays in particular including: map(), select() and invoke() where these are not yet provided by the native implementation.

Full details at http://documentcloud.github.io/underscore/

Chapter 3: String()

Avoid using new String() since the typeof function confusingly returns object and the complex object provided by using the new keyword is less performant.

String properties and methods

Chapter 4: Number()

As with strings, avoid using new Number().

Number properties and methods

The Number() object itself has a few useful properties: MAX_VALUE, MIN_VALUE, NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY

Instance methods include: toString(), valueOf()

Chapter 5: Boolean()

Any valid JavaScript value that is not 0, -1, null, false, NaN, undefined or empty string ("") will be converted to true when creating a boolean.

Beware, this means that a 'false' Boolean object (as opposed to a false boolean primitive value) will actually be true.