I recently read Nicholas Zackas’ The Principles of Object Oriented Javascript and I really recommend it. Many people I know (and students I teach) struggle with mapping the concept of object orientation onto a language that does not follow classical inheritance and lacks many of the visible signals that developers recognize as OO-ish.

The books makes forays into hidden attributes of the language but remains friendly throughout. It offers practical tools and exploratory exercises that will help JavaScript programmers learn more about this interesting and protean language.

I wrote the following precis of my take-aways:

  1. Introduction: OO Languages
  2. Encapsulation
  3. Aggregation (an object can reference another)
  4. Inheritance
  5. Polymorphism
  6. Javascript has these, but they are implemented in a way that appears different
  7. Primitive and Reference Types
  8. Primitive types: simple data
  9. Reference types: stored as objects
  10. Autoboxing casts primitive types to reference types
  11. Primitive Types 1. Boolean 1. Number 1. String 1. Null: A primitive type with only one value, null 1. Undefined: Primitive type with only value undefined, value assigned to uninitialized value 1. A variable holding a primitive holds the value 1. IDENTIFY WITH: typeof operator 1. SCREWBALL: typeof null // => "object" 1. Identify nullity by === null 1. Primitives are autoboxed to provide them an OO interface, but they are not objects
  12. Reference Types 1. Represent objects in JavaScript 1. Reference values are instances of reference types 1. An object is an unordered list of properties consisting of a name and a value 1. When the value points to a function it is called a method 1. Creating Objects
    1. Use new
    2. Assigned variable holds a pointer
      1. Destroying can be accomplished by assigning null and letting the GC clean
      2. Properties can be added or removed at any time.
  13. Instantiating Built-in Types 1. Array, Date, Error, Function, Objecdt, RegExp 1. Many of them have literal forms: Object, Array, RegExp 1. Object literal does not actually fire new Object()
  14. Property Acess 1. Dot notation 2. Bracket-and-String
  15. Identifying Reference Types: instance instanceof Class
  16. Identifying Arrays Array.isArray()
  17. Primitives are wrapped (autoboxed)
  18. Functions
  19. Functions have an internal property named [[Call]]
  20. Presence of [[Call]] means typeof returns “function”
  21. Declarations v. Expressions 1. Declaration: function foo() 1. Expression: var x = function() 1. Function declarations are hoisted and thus can be used before definition
  22. Functions can be used as values
  23. Parameters 1. You can pass any number of parameters 1. arguments object exists with all passed parameters 1. arguments is not an Array 1. Overloading function definitions is not possible 1. this: The currrent execution context
    1. Can be changed by three means
    2. call
    3. apply
    4. bind
  24. Understanding Objects
  25. Defining Properties 1. When a property is put on an object, [[Put]] is called
    1. Allocates the memory
    2. Specified initial value and attributes about the property
    3. This results in an own property
      1. When a property is updated on an object, [[Set]] is called
    4. Replaces the current value
      1. Detecting Properties
    5. Use the in operator: "name" in person1
    6. May want to test person1.hasOwnProperty("name") to preclude Prototype tampering
      1. Removing properties
    7. Don’t merely set to null
    8. DO use the delete operator
  26. Enumeration 1. By default all properties you add are enumerable 1. Properties have the internal [[Enumerable]] attributes set to true 1. To get a list of propereties, use Object.keys(): only returns instance properties! 1. Test whether a property is enumerable with propertyIsEnumerable()
  27. Types of properties 1. Two types
    1. Data properties: contain a value
    2. Accessor properties: don’t contain a value, but a function that returns a value (i.e. a “getter”)
      1. Define getter with: get propertyName(){}
      2. Define setter with: set propertyName(){}
  28. Property Attributes 1. Common
    1. [[Enumerable]]: Can be enumerated?
    2. [[Configurable]]: Can be changed?
    3. By default all properties are both
    4. Change with Object.defineProperty(objectOwner, propertyName, propertyDescriptorObject)
      1. Data Property Attributes
    5. To additional properties not found in property attributes
    6. [[Value]]: Holds the actual value
    7. [[Writable]]: Can be overwritten?
      1. Data Property Attributes
    8. [[Get]]: Holds the actual value
    9. [[Set]]: Can be overwritten?
      1. Multiple properties can be defined with Object.defineProperties()
  29. Preventing Object Motification 1. Object.preventExtension() sets the [[Extensible]] flag to false 1. Seal the object with Object.seal(): existing things can be changed 1. Freeze the object with Object.freeze(): non-ext; unchangeable
  30. Constructors and Prototypes
  31. Constructor is a function used with new to create an Object 1. Ensures siilarity of properties and methods 1. new will invoke even with out () 1. instanceof can determine whether an instance is from a constructor 1. When created with new a constructor property is set on the instance such that instance.constructor === ConstructorFunction is true
  32. Prototype 1. in operator returns true for both proto properties and own properties 1. An instance keeps track of its prototype with [[Prototype]] 1. Read prototype with Object.getPrototypeOf() 1. Test if something is prototype with object.isPrototypeOf(instance) 1. Set prototype with Object.setPrototypeOf()
  33. Inheritance
  34. Prototypal Inheritance
  35. Instances inherit their prototype, the proto inherits from its prototype
  36. See Listing 1

Listing 1

function Animal(species) {
  this.species = species

Animal.prototype.eat = function() {
  console.log("As a: " + this.species + ", I like to eat, yum yum");

function Person(name) {
  Animal.call(this, "Homo Sapiens");
  this.__proto__ = new Animal
  this.name = name;

var k = new Person("Chris");