Object Functions, Constructors and Prototypes


Collapse Content

Javascript is Object-oriented, though it's pretty different than other common languages.

Functions in Objects


// Objects can contain functions.
var myObj = {
    myFunc: function(){
        return "Hello world!";
    }
};
myObj.myFunc(); // = "Hello world!"

// functions can access the object they're attached to using the 'this' keyword.
myObj = {
    myString: "Hello world!",
    myFunc: function(){
        return this.myString;
    }
};
myObj.myFunc(); // = "Hello world!"

// The function's behavior depends on how it's called, not where it's defined. 
// So, our function doesn't work if it isn't called in the context of the object.
var myFunc = myObj.myFunc;
myFunc(); // = undefined

// Inversely, a function can be assigned to the object and gain access to it through 'this', 
// even if it wasn't attached when it was defined.
var myOtherFunc = function(){
    return this.myString.toUpperCase();
}
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"

Applying functions to objects


// You can specify a context for a function to execute in by invoking it using 'call' or 'apply'.
var anotherFunc = function(s){
    return this.myString + s;
}
anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"

// The 'apply' function is nearly identical, but takes an array for an argument list.
anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"

// This is useful when working with a function that accepts a sequence of arguments
// and you want to pass an array.
Math.min(42, 6, 27); // = 6
Math.min([42, 6, 27]); // = NaN (uh-oh!)
Math.min.apply(Math, [42, 6, 27]); // = 6

// 'call' and 'apply' are only temporary, use 'bind' to get it to stick 
// (so 'this' within the function will refer to the given object.)
var boundFunc = anotherFunc.bind(myObj);
boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"

// Bind can also be used to partially apply (curry) a function.
var product = function(a, b){ return a * b; }
var doubler = product.bind(this, 2);
doubler(8); // = 16

Constructor Functions

Constructors are functions designed to create objects. This is done by calling the function with the new keyword. Constructors use the this keyword to set properties of the object.

var MyConstructor = function(){
    this.myNumber = 5;
}
myNewObj = new MyConstructor(); // = {myNumber: 5}
myNewObj.myNumber; // = 5

Prototypes

Instead of classes, every JavaScript object has a 'prototype'. When you try to access a property on an object that doesn't exist on the actual object, the interpreter will look at its prototype.

Some JS implementations let you access an object's prototype with the magic property __proto__. This is useful for explaining prototypes, so we'll use it first.


var myObj = {
    myString: "Hello world!"
};
var myPrototype = {
    meaningOfLife: 42,
    myFunc: function(){
        return this.myString.toLowerCase()
    }
};

myObj.__proto__ = myPrototype;
myObj.meaningOfLife; // = 42

// This works for functions, too.
myObj.myFunc(); // = "hello world!"

// Of course, if your property isn't on your prototype, the prototype's
// prototype is searched, and so on.
myPrototype.__proto__ = {
    myBoolean: true
};
myObj.myBoolean; // = true

// There's no copying involved here; each object stores a reference to its prototype. 
// This means we can alter the prototype and our changes will be reflected everywhere.
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43

Standard Prototype Usage

__proto__ is non-standard, and there's no standard way to change the prototype of an existing object. However, there are two ways to create a new object with a given prototype. Click below for the code, which is continued from the above code on constructors and prototypes.

Using Prototypes (toggle)

Challenge

What will the following code print?

//create car object
var car = {
    speed: 0,
    increaseSpeed: function(){
        this.speed += 5;
    }
};

//two attempts to increase the car's speed.

var increaseSpeed = car.increaseSpeed;
increaseSpeed();

var accelerate = function(amount){
    this.speed += amount;
}
car.accelerate = accelerate;
car.accelerate(8);

console.log(car.speed);

Please sign in or sign up to submit answers.

Alternatively, you can try out Learneroo before signing up.

Challenge

Create 10 cars, where each car has a color and number. The cars should be numbered in order from 0 to 9. The cars from 0 to 4 should be colored "green" and the cars from 5 to 9 should be colored "blue". Place the cars in order in an array called carGarage.

Guideline:
To avoid duplicate code when creating 10 separate cars, first first create a constructor function Car that takes color and number parameters and sets them to this.color and this.number. Then create 10 cars and place them in a carGarage array.

Please sign in or sign up to submit answers.

Alternatively, you can try out Learneroo before signing up.

Contact Us
Sign in or email us at [email protected]