Object-Oriented JavaScript (yes, it really exists)

Jordan Kasper

jordan@jordankasper.com | @jakerella

You can view these slides at http://jordankasper.com/preso/oop-js

Shortly after it arrived at my home in 1993, I began disassembling my first computer... my mother was not happy. I quickly moved from hardware into programming, creating simple games on my i386 and, soon, various TI calculators. In 1997 I began working on my first web sites, they were crude and ugly. My focus has been on building better, cleaner web applications ever since.

I have worked for companies large and small, including startups and a large university; I am a contributor on a number of open source projects and regularly participate in community events. Teaching and speaking is a way of life, and I love evangelizing the good technology and traits I've found over the years. My primary technologies are PHP and JavaScript (and all of the supporting technologies around them). In my down time I enjoy puzzles of all sorts and board games.

Image reference: http://...

Take Aways

  1. OOP primer (language agnostic)
  2. The JavaScript object model
  3. Prototypical inheritance
  4. The future of OOP in JavaScript (er, ECMAScript)
  5. Some frameworks (if we have time)

OOP Primer

What is Object Oriented Programming (OOP)?

A way of representing things as collections of code with data and actions, including mechanisms for reusing code among related collections.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
            

OOP Primer - Core Concepts

What is Object Oriented Programming (OOP)?

These are what I consider the "core" concepts of Object Oriented Propgramming. While there may be dispute on what each one entails, almost all OOP languages implement these four.

  1. Abstraction
  2. Encapsulation
  3. Inheritance
  4. Polymorphism

OOP Primer - Abstraction

Creating an interface to store data and perform actions on a collection, thereby reducing and factoring out details so that a developer can focus on the problem domain.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
          
Note that with "abstraction" there is the idea that we have some decsription of a generic type of object separated from the object itself. In many OOP languages these are referred to as "classes" and "instances". In JavaScript, however, we have "prototypes" and "instances".

OOP Primer - Encapsulation

Part of Abstraction is creating an interface for your object model, and abstracting - or hiding - implementation of the actions of that model is Encapsulation.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
          
Note that some people would only consider it "Encapsulation" if the implementation of methods is restricted to other pieces of the code, but this is not a unanimous view.

OOP Primer - Inheritance

Can you explain the relationship between two objects "A" and "B" by: "A is a B" within the code structure provided in the language?

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
          

Note that HOW inheritance is implemented is not part of being object-oriented. Different languages will implement this differently, but in the end, most of them result in copying the data and actions from all parent classes to their sub classes.

Fun fact: Inheritance was first conceived for the Simula languages in 1968.

OOP Prime - Polymorphism

Literally: "many forms". The ability for a member of a collection to have different forms within the inheritance chain without changing the interface exposed outside the object.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
          
Note that there are typically two ways of doing this: method and property overridding and method overloading. Because JavaScript allows for variable method parameters - and does not restrict the number of parameters passed to a method - overloading can either be thought of as not supported or supported inherently in every method (overridden or not).

OOP Primer - Other Concepts

These concepts are not essential to being "Obejct-Oriented", but you do find them in quite a few implementations - so it's good to know about them.

  1. Interfaces
  2. Abstracts
  3. Public, Private, Protected
  4. Static Members

OOP Primer - Interfaces

Interfaces allow for certain members to be added to a collection, even when the colection does not inherit from the Interface.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections with Domesticated traits {
  have a "last vet visit" property
}
collections of type Dog are a type of Animal
                   and have traits of Domesticated {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
          

OOP Primer - Abstracts

Abstracts are a basic contract that requires any implementing collection to at the very least have the given interface, but the Abstract collection does not indicate how to implement the interface.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections that want to be Domesticated {
  must implement a "take to vet" action
}
collections of type Dog are a type of Animal and are Domesticated {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
  have a "take to vet" action 
    which updates the "last vet visit" property value
}
          

OOP Primer - Public, Private, Protected

All OOP languages implement "public" members - those that are accessible outside of the collection itself - but some also implement "private" - only accessible within the collection - and "protected" - accessible in the collection and down the inheritance chain.

collections of type Animal {
  have an "alive" property that defaults to true and is private
  have a "genus" property that defaults to null and is protected
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
          
Note that if not specified, the member is typically considered "public" - although many languages make you specify which type a member is. Also note that most language force inherited collection members to assume the access level of the parent class member (if it exists) or a level that is MORE open in order to preserve the interface definition.

OOP Primer - Static Members

Static members are defined once on a collection and not per instance, making them efficient ways to implement rarely changing data.

collections of type Animal {
  have an "alive" property that defaults to true
  have a "die" action that turns the "alive" switch to false
}
collections of type Dog are a type of Animal {
  when created, can be given a "name" property value
  have a "name" property that has no default
  have a "speak" action that makes it bark
  have a "die" action, but Dog groans after "alive" is switched
}
A Dog has a "genus" property with a value of "Canis"
          
In most languages, a static member is defined once, and is available to all objects without being on any one instance - this allows for better memory use and consistency in implementation of that property or action.

What is JavaScript?

I thought JavaScript was a Functional language?

The Functional paradigm (strictly speaking) states that any domain problem can be solved by combining a series of mathematical functions.

Any function should return the same value for the same input every single time (in other words, there is no application "state").

// Functional!
function sum(x, y) {
  return x+y;
}

// Not so much...
var x = 1;
function addTo(y) {
  return x+y;
}
        

What is JavaScript?

You can write JavaScript in a functional manner, and functions are first-class members of the language, but JavaScript also has a solid object model.

Conclusion: JavaScript is a multi-paradigm language.

In fact, "JavaScript" doesn't even appear in the Wikipedia entry for "Functional Programming".

What is JavaScript?

But JavaScript isn't really object-oriented...

O rly? Everything in JavaScript is an object!

var name = "Jordan";
// get the "length" property of the "name" object
name.length; // 6
// Get the decimal value of the length t one digit
name.length.toFixed(1); // 6.0
// call the "toUpperCase" method of the "name" object
name.toUpperCase(); // "JORDAN"
          

In case you're curious, behind the scenes, JavaScript is boxing these "primitives"...

what your write            what gets executed
  name.length     ==   (new String (name)).length;
          

A good reason to cache primitive properties for reuse.

What is JavaScript?

Even our functions are objects!

function foo() {
  return "bar";
}
// Get the name of our function
foo.name; // "foo"
foo.toString(); // "function foo() { return \"bar\" }"
        

FYI, the only things that aren't objects are null and undefined.

Basic Objects

Literally Basic

Super simple example: object literals...

var literalDog = { // definition AND instantiation
  name: "Vincent", // object property
  speak: function() { // object method
     // we use "this" to reference the current object instance
    return this.name+" says woof";
  }
};

// Access an object property
literalDog.name; // "Vincent"
// Use an object method
literalDog.speak(); // "Vincent says woof"
        

Literally Basic

And we use our literal objects like so...

var literalDog = { // definition AND instantiation
  name: "Vincent", // object property
  speak: function() { // object method
    // we use "this" to reference the current object instance
    return this.name+" says woof";
  }
};

// Access an object property
literalDog.name; // "Vincent"
// Use an object method
literalDog.speak(); // "Vincent says woof"
        

Literally Basic

So why not always use object literals?

var literalDog = {
  name: "Vincent",
  speak: function() {
    return this.name+" says woof";
  }
};
        

Remember, this is definition and instantiation...

literalDog.name = "Brian"; // new name!
literalDog.speak(); // "Brian says woof"
          

So how do we get a second dog?

Literally Basic

If you want a second dog, you have to recreate the whole thing:

var dogOne = {
  name: "Vincent",
  speak: function() {
    return this.name+" says woof";
  }
};

var dogTwo = {
  name: "Brian",
  speak: function() {
    return this.name+" says woof";
  }
};

dogOne.speak(); // "Vincent says woof"
dogTwo.speak(); // "Brian says woof"
        
There are, of course, other issues here... you can't use "instanceof", you can't do inheritance, and there is no real organization.

A New Dog

There has to be a better way!

function Dog(name) {
  this.name = name;
  this.speak = function() {
    return this.name+" says woof";
  }
}

var v = new Dog("Vincent");
v.speak(); // "Vincent says woof"
var b = new Dog("Brian");
b.speak(); // "Brian says woof"
        

A New Dog

There has to be a better way!

function Dog(name) {
  this.name = name;
  this.speak = function() {
    return this.name+" says woof";
  }
}

var v = new Dog("Vincent");
v.speak(); // "Vincent says woof"
var b = new Dog("Brian");
b.speak(); // "Brian says woof"
        

The Prototypical Dog

How does it work?

When we define our Dog, we get a new Dog prototype object...


  function Dog(name) {
    this.name = name;
    this.speak = function() {
      return this.name+" says woof";
    }
  }
            

=>

  Dog.prototype
  {
    constructor: Dog(name) {
      this.name = name;
      this.speak = function() {
        return this.name+" says woof";
      }
    },
    __proto__: Object { ... }
  }
              

Notice how our "name" and "speak" members are NOT in our prototype!

Note that the constructor IS the function we created, not any new thing. Also note that the prototype does NOT contain the "name" or "speak" members, this is because they are only first introduced in the constructor, so if the constructor isn't called, they won't exist.

Instanciful

When we use the "new" keyword...

var v = new Dog("Vincent");
        

JavaScript is actually taking two actions:

  1. Copy the desired prototype to a new object
  2. Call the constructor method on the instance

Instanciful

In fact, we can split these actions ourselves...

// copy the Dog prototype to our new instance
var v = Object.create(Dog.prototype);

// call the constructor function ("Dog" in our case)
v.constructor("Vincent");

v.speak(); // "Vincent says woof"
        

Note that Object.create() does not exist in IE < 9,
but you can use a shim, see the example code link at the end to see how.

Note that the "Object.create" function will not exist in versions of IE < 9, but you can use a shim to make it work. See my examples st the end of the slides.

A Better Dog

Remember that the "name" and "speak" members were not on the prototype?
We probably want them to be...

function Dog(name) {
  // a little check to see that a name was passed in
  if (name) { this.name = name; }
}
 // With prototype members we can set a default value
Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
};

var b = new Dog(); // no name passed in
b.speak(); // "Bubbles says woof"
        

The Prototypical Dog: Redemption

Our new Dog, has a better prototype:



function Dog(name) {
  if (name) { this.name = name; }
}
Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
};
          

=>

Dog.prototype
{
  constructor: Dog(name) {
    if (name) { this.name = name; }
  },
  name: "Bubbles",
  speak: function() {
    return this.name+" says woof";
  },
  __proto__: Object { ... }
}
            

Dun dun dun...

Most browsers give object instances access to their prototype via the __proto__ property.
(That's pronounced "dunder proto", as in: "double underscore proto")

function Dog(name) {
  if (name) { this.name = name; }
}
Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
};

var b = new Dog("Brian");
b.__proto__ == Dog.prototype; // true!
        

Technically, __proto__ has been deprecated in the current version of JavaScript (1.8.5), but it will be coming back in ECMAScript 6. If you want to be a bit cautious, you can also use Object.getPrototypeOf(someObject);

For browsers that don't support the __proto__ property, you can simply add this in your constructor:
if (!({}).__proto__) { this.__proto__ = YourObject.prototype; }

Member Access Types
Public, Private, and Privileged

(Sorry, no "protected")

Public Access - Cable 10, Aurora, IL

Public Members

Any member attached to a prototype is public!

function Dog(name) {
  if (name) { this.name = name; }
}
Dog.prototype.name = "Bubbles";     // public
Dog.prototype.speak = function() {  // public
  return this.name+" says woof";
};
        

Public Access - Cable 10, Aurora, IL

Public Members

Note that if you add a member directly on the instance it will be public as well!

function Dog(name) {
  if (name) { this.name = name; }
  this.fur = "black";               // public
}
Dog.prototype.name = "Bubbles";     // public
Dog.prototype.speak = function() {  // public
  return this.name+" says woof";
};

var d = new Dog();
d.owner = "Jordan";                 // public
        

The Private Life of a Dog

Private Variables

Variables declared inside a function only exist while that function's context exists.

function Dog(name) {
  if (name) { this.name = name; }
  // notice that we don't use "this."!
  var alive = true; // private to the constructor only
}
...

var b = new Dog("Brian");
b.alive; // undefined!
        

The Private Life of a Dog

Privileged Methods

If we want access to a private variable we have to create a "privileged" method...

function Dog(name) {
  if (name) { this.name = name; }
  // notice that we don't use "this."!
  var alive = true;                           // private
  this.isAlive = function() { return alive; } // privileged
  this.die = function() { alive = false; }    // privileged
}
...
        

We are able to access the alive property from within the isAlive and die methods because JavaScript maintains the state in which a function was declared (commonly known as a closure).

The Private Life of a Dog

Privileged Methods

And we can use a privileged method just like a public method...

function Dog(name) {
  if (name) { this.name = name; }
  // notice that we don't use "this."!
  var alive = true;                           // private
  this.isAlive = function() { return alive; } // privileged
  this.die = function() { alive = false; }    // privileged
}
...

var b = new Dog("Brian");
b.isAlive(); // true :)
b.die();
b.isAlive(); // false :(
b.alive;     // still undefined!
        

The Private Life of a Dog

Privileged Methods

A public method added to the prototype will not have access to private variables,
but it will not throw an error either!

function Dog(name) {
  if (name) { this.name = name; }
  var alive = true;                           // private
  this.isAlive = function() { return alive; } // privileged
  this.die = function() { alive = false; }    // privileged
}
...
Dog.prototype.kill = function() { this.alive = false; } // NOT privileged

var b = new Dog("Brian");
b.kill();    // makes this.alive false;
b.isAlive(); // still true!
        

When we called b.kill(); we created a new public member with the same name as the private member, but in different contexts.

Static Cling

Static Members

Static variables can be defined on any object. Because functions are objects, we can put our static members directly on our Dog constructor function.

function Dog(name) {
  if (name) { this.name = name; }
}
Dog.prototype.name = "Bubbles";     // instance property
Dog.prototype.speak = function() {  // instance method
  return this.name+" says woof";
}
Dog.GENUS = "Canis";                // static property
Dog.mergeBreeds = function(a, b) {  // static method
  return ("Breeding "+a+" and "+b);
}

console.log(Dog.GENUS); // prints: Canis
        

Static Cling

Be careful when using static methods, you can't call them from an instance, nor can you access an instance using this inside them.

function Dog(name) {
  if (name) { this.name = name; }
}
Dog.getName = function(name) {
  return this.name;  // what is "this" pointing to?
}

Dog.getName(); // what will this return?

var v = new Dog("Vincent");
v.getName(); // throws error: "getName" does not exist on the instance!
        
Dog.getName() above will always return "Dog" because "this" inside of "getName" will always refer to the object the function is defined within, which is our constructor function named "Dog".

Inheritance!

That's so typical...

Classical Inheritance

Also known as "class-based" inheritance;
Classes have subclasses which extend existing functionality. Instances of a class use the functionality (and some data) of each parent class.

Prototypical Inheritance

There is only the prototype. Prototype objects are exemplars of an instance - all members of the prototype are copied to each instance. A new prototype can be created from an existing prototype, thus extending the original functionality (typically called the prototype-chain).

It's a Dog-Eat-Dog World

function Animal() {
  var alive = true;
  this.isAlive = function() { return alive; }
  this.die = function() { alive = false; }
}

function Dog(name) {
  // call parent constructor with "this" as the context, and any arguments
  Animal.apply(this, [arg1, arg2, ...]);
  if (name) { this.name = name; }
}
Dog.prototype = Object.create(Animal.prototype); // the magic happens
Dog.prototype.constructor = Dog;                 // on these two lines

Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
}
        

Chain Gang

Our prototype chain

The prototype chain

Back on the Chain Gang

Prototype Definition

function Animal() {
  var alive = true;
  this.isAlive = function() { return alive; }
  this.die = function() { alive = false; }
}

function Dog(name) {
  Animal.apply(this, [...]);
  if (name) { this.name = name; }
}
// THE MAGIC!
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
}
            

Prototype Chain

var v = new Dog("Vincent");
console.log( v );

console:
{
  name: "Vincent",
  __proto__: Dog {
    constructor: function Dog(name) { ... }
    name: "Bubbles"
    speak: function () { ... }
    __proto__: Animal {
      constructor: function Animal() { ... }
      __proto__: Object { ... }
    }
  }
}
            

*Sniff* ... What is it?

Prototype Definition

function Animal() {
  var alive = true;
  this.isAlive = function() { return alive; }
  this.die = function() { alive = false; }
}

function Dog(name) {
  Animal.apply(this, [...]);
  if (name) { this.name = name; }
}
// THE MAGIC!
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
}
            

Creating Instances

var v = new Dog("Vincent");
v.speak();   // "Vincent says woof"
v.isAlive(); // true

(v instanceof Dog);    // true
(v instanceof Animal); // true
(v instanceof Object); // true

Dog.prototype.isPrototypeOf( v );    // true
Animal.prototype.isPrototypeOf( v ); // true

var a = new Animal();
(a instanceof Animal); // true
(a instanceof Dog);    // false
            

Back to the Source

Calling parent methods isn't too difficult, if a bit wordy...

function Animal(age) {
  this.age = age;
  ...
}
Animal.prototype.age = 1;
Animal.prototype.getAge = function() { return this.age; }

function Dog(name, age) {
  Animal.apply(this, [age]);
  if (name) { this.name = name; }
}
Dog.prototype.getAge = function() {
  // call the parent method first
  var age = Animal.prototype.getAge.call(this);
  return (age * 7);
}

var v = new Dog("Vincent", 8);
v.getAge(); // 56
        

Note that privileged methods can be overridden, but you cannot call the parent method!

Magnum P.I. (Prototype Interface)

While there aren't "proper" interfaces in prototypical inheritance, we can accomplish similar functionality by copying members from an object literal to a prototype.
(Most people in the OO JS world call this a "mixin".)

function Animal() {
  ...
}
...
function Dog(name) {
  ...
}
...

// our interface/mixin
var Domesticated = {
  happiness: 1,
  lickFace: function(times) {
    this.happiness += times;
  }
};
        

Magnum P.I. (Prototype Interface)

We need to use a helper method to mixin (implement) our interface on a given prototype...
do not write this yourself!

// jQuery ($), Underscore (_), or Angular (ng)
$.extend(target, obj1, obj2, ...);

// Prototype
Object.extend(target, obj);

// Backbone
Model.extend({ ... });

// Dojo
lang.mixin(target, obj);
// or us extend, which adds to the prototype automatically
lang.extend(Class, obj);
          

Magnum P.I. (Prototype Interface)

Now we simply call the extend function on our Dog prototype...



// jQuery ($)
$.extend(target, obj1, obj2, ...);


// implement "Domesticated" on our "Dog" prototype
$.extend(Dog.prototype, Domesticated);

var v = new Dog("Vincent");
v.happiness; // 1
v.lickFace(5);
v.happiness; // 6
          

Space, the Final Nametier

JavaScript doesn't have "packages" like some languages, but you can (and should) namespace your code with simple object literals.

// this is my namespace definition
var jk = {};

// Before we used: function Animal() { ... }
jk.Animal = function() {
  ...
}
jk.Animal.prototype = ...
jk.Dog = function(name) {
  ...
}
jk.Dog.prototype = Object.create(jk.Animal.prototype);
jk.Dog.prototype.constructor = jk.Dog;
jk.Dog.prototype = ...

var v = new jk.Dog("Vincent");
        

Let's Review...

OOP Core Concepts

What about our OOP core (and secondary) concpets? Has JavaScript met them?

Core

  1. Abstraction
  2. Encapsulation
  3. Inheritance
  4. Polymorphism

Secondary

  1. Interfaces
  2. Abstracts
  3. Public, Private, Protected
  4. Static Members

OOP Core Concepts

What about our OOP core (and secondary) concpets? Has JavaScript met them?

Core

  1. Abstraction
  2. Encapsulation
  3. Inheritance
  4. Polymorphism

Secondary

  1. Interfaces
  2. Abstracts
  3. Public, Private, Protected
  4. Static Members

OOP Core Concepts

What about our OOP core (and secondary) concpets? Has JavaScript met them?

Core

  1. Abstraction
  2. Encapsulation
  3. Inheritance
  4. Polymorphism

Secondary

  1. Interfaces
  2. Abstracts
  3. Public, Private, Protected, Priveleged
  4. Static Members

The Future

The Future - The Year 2000

Recent History of ECMAScript
(parent specification of JavaScript)

* Only minor things missing.

The Future - The Year 2000

ECMAScript 6 Classes

To make things easier for new JavaScript developers, some new syntactic sugar has been added...


function Dog(name) {
  Animal.apply(this, [...]);
  if (name) { this.name = name; }
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.name = "Bubbles";
Dog.prototype.speak = function() {
  return this.name+" says woof";
}
Dog.prototype.getName = function() {
  return this.name + " (the dog)";
}
          

class Dog extends Animal {
  constructor(name) {
    super(); // Call parent method of same name
    if (name) { this.name = name; }
  }

  get name() {
    return this.name + " (the dog)";
  }

  speak() {
    return this.name+" says woof";
  }
}

// for data members, we still have to do this...
Dog.prototype.name = "Bubbles";
            

But remember, this is just syntactic sugar, nothing has really changed.

The Future - The Year 2000

Other ECMAScript 6 Goodies

Don't write a framework!

Frameworks

There are many good frameworks that abstract away the creation of objects and extending of base objects for you.

Don't rediscover sliced bread!

In case you're curious, you can implement OOP JavaScript concepts in any engine, including server-side technologies like Node.js and Rhino (both of which support ECMAScript 5).

Object-Oriented JavaScript (yes, it really exists)

Thank you!

Jordan Kasper

jordan@jordankasper.com | @jakerella

You can view these slides at http://jordankasper.com/preso/oop-js

Some references