- About Javascript
- Javascript Basics
- Strings, Arrays and Objects
- Control Structures
- Functions, Scope and Closures
- Object Functions, Constructors and Prototypes
- Javascript Next
Example code based on
LearnXinYminutes
and licensed under
CC Attribution-Share 3
Object Functions, Constructors and Prototypes
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.
// The first way is Object.create, which is a recent addition to JS,
// and therefore not available in all implementations yet.
var myObj = Object.create(myPrototype);
myObj.meaningOfLife; // = 43
// The second way, which works anywhere, has to do with constructors:
// Constructors have a property called prototype. This is *not* the prototype of
// the constructor function itself; instead, it's the prototype that new objects
// are given when they're created with that constructor and the new keyword.
MyConstructor.prototype = {
myNumber: 5,
getMyNumber: function(){
return this.myNumber;
}
};
var myNewObj2 = new MyConstructor();
myNewObj2.getMyNumber(); // = 5
myNewObj2.myNumber = 6
myNewObj2.getMyNumber(); // = 6
// Built-in types like strings and numbers also have constructors
// that create equivalent wrapper objects.
var myNumber = 12;
var myNumberObj = new Number(12);
myNumber == myNumberObj; // = true
// Except, they aren't exactly equivalent.
typeof(myNumber); // = 'number'
typeof(myNumberObj); // = 'object'
myNumber === myNumberObj; // = false
if (0){
// This code won't execute, because 0 is falsy.
}
if (Number(0)){
// This code *will* execute, because Number(0) is truthy.
}
// However, the wrapper objects and the regular builtins share a prototype, so
// you can actually add functionality to a string, for instance.
String.prototype.firstCharacter = function(){
return this.charAt(0);
}
"abc".firstCharacter(); // = "a"
// This fact is often used in "polyfilling", which is implementing newer
// features of JavaScript in an older subset of JavaScript, so that they can be
// used in older environments such as outdated browsers.
// For instance, we mentioned that Object.create isn't yet available in all
// implementations, but we can still use it with this polyfill:
if (Object.create === undefined){ // don't overwrite it if it exists
Object.create = function(proto){
// make a temporary constructor with the right prototype
var Constructor = function(){};
Constructor.prototype = proto;
// then use it to create a new, appropriately-prototyped object
return new Constructor();
}
}
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.