Object-Oriented JavaScript

Hybrid Style

As context for this lesson, see the hybrid styles lesson before, and come back to it after.


JavaScript is a hybrid of (at least) three styles:

What is an Object?

Definition of Object

An object...

True Object-Oriented Programming

Object vs. Object

The Linguistic Metaphor for Objects

One way to think about objects:

Objects are things that can be described and can do things, or...

Creating an object literally

let dog = {color: "brown"}

References and Instances

Stack Heap
dog -> {color: "brown"}

Literals create instances

let abby = {color: "brown"}
let lula = {color: "brown"}
Stack Heap
abby -> {color: "brown"}
lula -> {color: "brown"}

Side effects

let dog = {color: "brown"}
let lula = dog

lula.color = "gold"

dog.color // now the generic dog is golden too

Encapsulating State

Instance variables are properties of the object:

if (abby.color === 'brown') {
  console.log("Abby is a brown dog.");

Encapsulating Behavior

Instance methods are also properties of the object:

let abby = {color: "brown"};
abby.speak = function() {
abby.speak()     // prints "Bark!" to console

The above is fine as far as it goes, but it's not really object-oriented since speak isn't using any state...

"this" is it

var circle = {radius: 2};
circle.circumference = function() {
    return Math.PI * 2 * this.radius;
console.log(circle.circumference()); // 12.566370614359172
var biggerCircle = {radius: 4};
biggerCircle.circumference = circle.circumference;
console.log(biggerCircle.circumference()); // 25.132741228718345

...but "this" isn't always it!

JS Gotcha: you must remember this

Even inside an object, you must remember to use this., otherwise radius becomes a global variable, not a property.

var circle = {radius: 2};
circle.circumference = function() {
    return Math.PI * 2 * radius;  // Oops! Forgot "this."
circle.circumference() // returns NaN
// (or says 'radius is not defined' if you're lucky)

This is a terrible mistake in the language design; it undercuts one of the core principles of computer language design, which is to make the best way to do something also the easiest way to do that thing.

JS Gotcha: Fat Arrow and Binding

In most OO languages, the pointer this (sometimes named self) is managed automatically. Any time you're executing code inside class A, this is guaranteed to point to an instance of that class.

In JavaScript, this needs to be managed more actively.

Specifically, during callbacks this still points to the other object -- not the object where the function is defined!

Solution: the => fat arrow re-binds this to point to the current object.

More on "this" and binding

circle1.circumference()      // OK -- this = circle1
circle2['circumference']()   // OK -- this = circle2
var g = circle.circumference;
g();                        // BAD -- this = window, so this.radius = undefined, so result is NaN

this and callbacks

$('#someButton').click((event) =>
    this.clickedButton = $(this).value();
var self = this;
$('#someButton').click(function(event) {
    self.clickedButton = $(this).value();

Next Lesson   Previous Lesson