Abstract

Notes on Douglas Crockford's Yahoo talk on Javascript

Table of Contents

Objects

An object is a dynamic collection of properties. Every property has a key string that is unique within that object. All values are objects except null and undefined

References

Basic functions

Get, Set, Delete

Delete

// sets to undefined

delete object.name 
delete object[expression] 

Properties

A property is a named collection of attributes:

To set the above:

Object.defineProperty(object, key, descriptor)
Object.defineProperties(object, objectOfDescriptors)

Object.getOwnPropertyDescriptor(object,key)
Object.getOwnProperties(object)

Object.keys(object)

Object literals and:

var my_object = Object.defineProperties(Object.create(Object.prototype) {
    foo: {
        value: bar,
        writeable: true,
        enumerable: true,
        configurable: true
    }
}); 

Two Kinds of

Accessor Properties

Don’t get stupid with this stuff. Be really, really careful with it.

Object.defineProperty(my_object, 
    'inch' {
        get: function () {
            return this.mm  / 25.4;
        },
        set: function (value) {
            this.mm = value * 25.4;
        },
        enumerable: true
    });

Classes and Prototypes

Prototypal method is very powerful.

Objects have a prototype attribute: object or null

Object.create(object, properties)
Object.getPrototypeOf(object) // shouldn't use.  You shouldn't care where an object came from.

Delegation: Differential Inheritance

You only add the differences to the object that you are working with.

new

Don’t use it. Use Object.create

Javascript didn’t get it quite right

Vid 2

Extensible Bit

Types in the Language

All based on Object

Number

Order of operations in numbers is critical

Associative Law Does Not Hold
(a + b) + c === a + (b + c) // produces false for some values of a,b,c.

Integers under 9 quadrillion are ok

Decimal fractions are approximate

Because of binary floating point (It does not accurately represent decimal numbers). You should turn it into integers.

a = 0.1;
b = 0.2; 
c = 0.3;

(a + b) + c === a + (b + c) //false
Number Methods
Adding a number method (45:08)
if (!Number.prototype.trunc) {
    Number.prototype.trunc = 
        function trunc(number) {
            return Math[
                number >= 0 ?
                    'floor' : 'ceil'
                ](number);
        };
}
Numbers are first class objects
Math object
NaN

String

Multi-line String Literals

dont use!

var long_line_1 = "This is a \
long line"; //ok

var long_line_2 = "This is a \ 
long line"; //failure because there is a space after the backslash
Convert string to number
trim function for browsers older than ES5 (57:00)
if (typeof String.prototype.trim !== 'function') {
    String.prototype.trim = function () {
        return this.replace(
            //regex
        );
    };
}
Supplant Method

lookup

Arrays

Length Property
When to use

RegExp

Rethink it if it is more than 2 inches.

typeof

returns ‘object’ with array and null

Identifiers

Comments

Only use //

Operators

%

-1 % 8 // -1 not 7

=== & !==

Always use === because of the evils of type coercion

&& sometimes called the gaurd operator

|| or logical or operator

! logical not operator / !!

Bitwise operators

Statements

labeled break:

loop: for (;;) {

    if (…) {
        break loop;
    } 
}

Switch

With

Don’t use it!


Vid 3: Functions

function expression

var statement

Function Statement

It is mainly just shorthand for the function expression

Scope

return

return expression;
return; //returns undefined except for constructors then the default value is this

Psuedo Params

arguments

When a function is invoked it gets a special param called arguments

this

Invocation

Function Form

functionName(args)

Constructor form

new FunctionValue(args)

Apply Form

Closure


Vid 3 (30:00) // See here!!!

Later Method

if (typeof Object.prototype.later !== 'function') {
    Object.prototype.later = function (msec, method) {
        var that = this,
            args = Array.prototype.slice
                    .apply(arguments, [2]);
        if (typeof method === 'string') {
            method = that[method];
        }
        setTimeout(function () {
            method.apply(that, args);
        }, msec);
        return that; //cascade
    };
}

Sealer/Unsealer 48:00 vid 3

function make_sealer() {
    var boxes = [], values = [];

    return {
        sealer: function (value) {
            var i = boxes.length, box = {};
            boxes[i] = box;
            value[i] = value;
            return box;
        },
        unsealer: function (box) {
            return values[boxes.indexOf(box)];
        };
    };
}

Prototypal Inheritance

var gizmo = new_constructor(Object, function (id) {
    this.id = id;
}, {
    toString: function() {
        return "gizmo " + this.id;
    }
});

var hoozit = new_constructor(gizmo, function (id) {
    this.id = id;
}, {
    test: function (id) {
        return this.id === id;
    }
});

New Constructor Function

function new_constructor(extend, initializer, methods) {
    var func, prototype = Object.create(extend && extend.prototype);

    if (methods) {
        methods.keys().forEach(function (key) {
            prototype[key] = methods[key];
        });
    }
    func = function () {
        var that = Object.create(prototype);
        if (typeof initializer === 'function') {
            initializer.apply(that, arguments);
        }
        return that;
    };
    func.prototype = prototype;
    prototype.constructor = func;
    return func;
}

Module pattern

A Module Pattern

GLOBAL.methodical = (function() {
    var privateVariable;
    function privateFunction(x) {
        …privateVariable…
    }
    return {
        firstMethod: function (a, b) {
            …privatevariable…
        },
        secondMethod: function (c) {
            …privateFunction()…
        }
    };
}());

Assigning Methods to predefined Namespace

(function () {
    var privateVariable;
    function privateFunction(x) {
        …privateVariable…
    }
    GLOBAL.firstMethod = function (a,b) {
        …privateVariable…
    };
    GLOBAL.secondMethod = function (c) {
        …privateFunction()…
    };
}());

Power Constructors

  1. Make an Object

    • Object literal
    • new
    • Object.create
    • call another power constructor
  2. Define Some Variables and functions

  1. Augment the object with priviledged methods.

  2. Return the object.


function myPowerConstructor(x) {
    var that = otherMaker(x);
    var secret = f(x);
    that.priv = function () {
        …secret x that…
    };
    return that;
}

Functional Inheritance

function gizmo(id) {
    return {
        toString: function () {
            return "gizmo " + id;
        }
    };
}

function hoozit(id) {
    var that = gizmo(id);
    that.test = function (testid) {
        return testid === id;
    };
    return that; 
}

Shared Secrets

function gizmo(id, secret) {
    secret = secret || ();
    secret.id = id;
    return {
        toString: function () {
            return "gizmo " + secret.id;
        }
    };
}

function hoozit(id) {
    var secret = {}; /*final*/
    var that = gizmo(id, secret);
    that.test = function (testid) {
        return testid === secret.id;
    };
    return that; 
}

Super Methods

y combinator 1:10

Little Schemer Book 1:12