On Github AnnieCannons / ac-object-oriented-js
Software is a collection of cooperating objects rather than a collection of functions or simply a list of commands.
Objects are so great because they contain DATA and FUNCTIONALITY
function diceRoll() { var sides = 6; var randomNumber = Math.floor(Math.random() * sides) + 1; console.log(randomNumber); } var dice = { };
var dice = { roll: function diceRoll() { var sides = 6; var randomNumber = Math.floor(Math.random() * sides) + 1; console.log(randomNumber); } };
Run dice.roll in the console.
How do we call the dice.roll function?var dice = { roll: function() { var sides = 6; var randomNumber = Math.floor(Math.random() * sides) + 1; console.log(randomNumber); } };
Run dice.roll() in the console.
If we have the sides as a property of the dice object, how will the function call it?
var dice = { roll: function() { var sides = 6; var randomNumber = Math.floor(Math.random() * sides) + 1; console.log(randomNumber); } };
var dice = { sides: 6, roll: function() { var randomNumber = Math.floor(Math.random() * dice.sides) + 1; console.log(randomNumber); } };
Now we can easily change the value of the property sides in our code by dice.sides=10.
"this" always points to the object that it has been linked to
var circle = { radius: 2 }; circle.circumference = function() { return Math.PI * 2 * this.radius; } console.log(circle.circumference()); // 12.566370614359172
"this" allows one function (method) to operate on many states (instances)
var biggerCircle = { radius: 4 }; biggerCircle.circumference = circle.circumference; console.log(biggerCircle.circumference()); // 25.132741228718345
var portland = { name: "Portland", bridges: 12, airport: 1, soccerTeams: 1, logNumberOfBridges: function () { console.log (“There are “ + this.bridges + “ bridges in ” + this.name); } } portland.logNumberOfBridges();
this is an identifier that gets a value bound to it, much like a variable.
But instead of identifiying the values explicitly in your code, this gets bound to the correct object automatically.
Object Literal
var flower = { color : "red", petals : 32, smellsPretty : true };
Constructor Object
function Flower(color, petals){ this.color = color; this.petals = petals; this.smellsPretty = true; }
Creating a user-defined object requires two steps:
Define the object type by writing a function. Create an instance of the object with new.Example:
//Defines the new object function Contact (name, email) { this.name = name; this.email = email; } //Creates the new instance var myContact = new Contact('Laura', 'laura@hello.com');
Important: the name of the function is capitalized so you know it is a constructor!
What would the name value be in myContact?
console.log(myContact.name);
What would the name value be in myOtherContact?
function Contact (name, email) { this.name = name; this.email = email; } //Creates the new instance var myOtherContact = new Contact('Hubs', 'hubs@hello.com'); console.log(myOtherContact.name);Why?
var myContact = new Contact('Laura', 'laura@hello.com');
Can you think of other specific times when you would need to use an object constructor?
Given the following code:
function Animal(species, noise) { this.species = species; this.noise = noise; this.makeNoise = function() { console.log(this.noise + ", " + this.noise); } }
How would you create an instance of an Animal?
How would you describe a task in a todo list. Your task should have:
function TodoListItem(description) { this.description = description; this.isDone = false; this.markAsComplete = function() { this.isDone = true; } } var task = new TodoListItem("Do the laundry!");
What kind of objects you might need for your new Social Media site?
What would be the properties on those objects?
If we run this code over and over again (to create new instances):
function City (name, nickname) { this.name = name; this.nickname = nickname; this.slogan = function () { console.log(this.name + " is the best city in the country!"); }; } var sanFrancisco = new City("San Francisco", "City By The Bay");
Every time we create an object, the program runs the code, and a new anonymous function is created again and again. Your program is taking up more space in the computer’s memory.
We can add a method onto this object constructor by using prototype.
function City (name, nickname) { this.name = name; this.nickname = nickname; } City.prototype.slogan = function(){ console.log(this.name + " is the best city in the country!"); } var sanFrancisco = new City("San Francisco", "City By The Bay"); sanFrancisco.slogan();
var Circle = function(radius) { this.radius = radius; } Circle.prototype.circumference = function() { return Math.PI * 2 * this.radius; } Circle.prototype.area = function() { return Math.PI * this.radius * this.radius; } var circle = new Circle(2); circle.radius; // this is 2; it's stored on the circle circle.area; // this is a function; it's stored on Circle.prototype circle.area(); // this is a function call; inside it, "this" points to the circle
A constructor function makes an object linked to its own prototype
function Greeter(who) { this.me = who; } Greeter.prototype.identify = function (){ return "I am " + this.me; }; var person1 = new Greeter("Alice"); var person2 = new Greeter("Bob"); person1.constructor === Greeter; person1.constructor === person2.constructor;
function Greeter(who) { this.me = who; } Greeter.prototype.identify = function() { return "I am " + this.name; }; Greeter.prototype.speak = function() { alert("Hello, " + this.identify() + "."); }; var person1 = new Greeter("Alice"); person1.speak():
function Greeter(who) { this.me = who; } Greeter.prototype.identify = function(){ return "I am " + this.me; } function Bar (who) { Greeter.call(this,who); } Bar.prototype = Object.create(Greeter.prototype); Bar.prototype.speak = function (){ alert("Hello, " + this.identity() + "."); } var customer1 = new Bar ("Viola"); var customer2 = new Bar ("Jamie"); customer1.speak();
// The constructor function function PaperBack(title, author, numPages, cover) { Book.call(this, title, author, numPages); this.cover = cover; } // Extending the Book object PaperBack.prototype = Object.create(Book.prototype); // A new method on this object PaperBack.prototype.burn = function() { console.log("Omg, you burnt all " + this.numPages + " pages"); this.numPages = 0; } // Instantiating a new object var paperback = new PaperBack("1984", "George Orwell", 250, "cover.jpg"); paperback.read(); paperback.burn();
function init() { var name = "Mozilla"; //name is a local variable created by init function displayName() { //displayName() is the inner function, a closure alert(name); } displayName(); } init();
This is an example of lexical scoping: in JavaScript, the scope of a variabe is defined by its location within the source code (it is apparent lexically) and nested functions have access to variable declared in their outer scope.
We have covered this: it is global and local!
A closure is created when an inner function is made accessible from outside of the function that created it. This typically occurs when an outer function returns an inner function. When this happens, the inner function maintains a reference to the environment in which it was created.
This means that it remembers all of the variables (and their values) that were in scope at the time.
Our friend Kyle Simpson
function sayHello(name){ var text = 'Hello ' + name; var say = function() { console.log(text) say(); } }
function sayHello2(name){ var text = 'Hello ' + name; //Local variable var say = function() { console.log(text) } return say; } var say2 = sayHello2('Bob'); say2(); // logs "Hello Bob"
function add(value1){ return function doAdd(value2){ return value1 + value2; }; } var increment = add(1); var foo = increment(2); //foo equal 3
The add() function returns its inner function doAdd(). By returning a reference to an inner function, a closure is created.
Things to Remember
function say667() { //Local variable that ends up within closure var num = 666; var say = function() { console.log(num); } num++; return say; } var sayNumber = say667(); sayNumber();
function nameAdder(x){ return function(y){ return x + y; }; } var add5 = makeAdder(5); var add10 = makeAdder(10);
Console log these variables
This also works if you are returning an object with methods.
function counter() { var n = 0; return { count: function() { return ++n; }; reset: function() { return n = 0; }; }; } var myCounter = counter();
Thank you for your attention!