GithubHelp home page GithubHelp logo

phrg-js-object-oriented-prototypes-readme's Introduction

Using Prototypes

Objectives

  • Understand how prototypes reduce the memory footprint of our objects.
  • Understand how to define a method on the prototype of a constructor function.
  • Understand how those methods can be executed on objects constructed from that function.

A problem we didn't know we had

We ended our lesson on constructing objects from a constructor function with the following code.

function User (name, email){
  this.name = name;
  this.email = email;
  this.sayHello = function(){
    console.log(`Hello everybody, my name is ${this.name}!`);
  }
}

let lauren = new User('lauren', '[email protected]')
lauren.sayHello()
// "Hello everybody, my name is lauren!"

let fred = new User('fred', '[email protected]')
fred.sayHello()
// "Hello everybody, my name is fred!"

This code works well, but we are not being very efficient. Let's see how.

  lauren.sayHello
  // function(){
  //   console.log(`Hello everybody, my name is ${this.name}!`);
  // }

  fred.sayHello
  // function(){
  //   console.log(`Hello everybody, my name is ${this.name}!`);
  // }

Both lauren and fred have a sayHello property that points to a seemingly identical function. But are these two objects pointing to the same function? No.

  lauren.sayHello == fred.sayHello
  // false

Think about why this is true. Every time that we instantiate a new object, we run our constructor function, which declares a new function as a property of the new object.

function User (name, email){
  this.name = name;
  this.email = email;
  this.sayHello = function(){
    console.log(`Hello everybody, my name is ${this.name}!`);
  }
}

The problem is that all of these functions are precisely the same. They only return different values because the value of this is dependent on the object whose method is being called. Well if we declare a new, yet identical function for every instance of a constructor we are being memory inefficient. That is, each instance of our object would be a different, yet identical, method attached to it. And in JavaScript, where our code needs to run in a memory-limited browser, this is something we would prefer to avoid. So what we want is a way to declare the function just one time, yet grant each object made from our constructor function a reference to this function.

Behold the Prototype!!

Javascript objects have something called a Prototype. Let's check it out.

function User(name, email) {
  this.name = name;
  this.email = email;
}

User.prototype.sayHello = function() {
  console.log(`Hello everybody, my name is ${this.name}`);
}

var sarah = new User("sarah", "[email protected]");

sarah.sayHello();
// "Hello everybody, my name is sarah!"

Let's reflect on what we just did. We moved our declaration of the sayHello function to outside of the constructor function User. This prevents the sayHello function from being redeclared each time a new user is created. However, we do want to give each constructed user object access to this function. To do so, we access the User function's prototype property. What is a prototype?

  User.prototype
  // {}
  typeof User.prototype
  // object

It's just a JavaScript object. That object can store specific attributes. The key point is that every new user instance made from the User constructor function has reference to attributes defined on User function's prototype object. So this lends to the following:

  function User(name, email) {
    this.name = name;
    this.email = email;
  }

  User.prototype
  // {}

  User.prototype.sayHello = function(){
    console.log(`Hello everybody, my name is ${this.name}`);
  }

  let sarah = new User('sarah', '[email protected]')

  sarah.sayHello()
  // "Hello everybody, my name is sarah!"

  let freddy = new User('freddy', '[email protected]')
  freddy.sayHello()
  // "Hello everybody, my name is freddy!"

  freddy.sayHello == sarah.sayHello
  // true

What the above code illustrates is each JavaScript object has reference to attributes declared on its constructor's prototype. So both sally and freddy have reference to the sayHello attribute that points to a specific function. Not only that, but they have reference to exactly the same function. So regardless of the number of objects produced from the User constructor, there will be only one declared sayHello function.

Going forward with constructor functions, it's best to separate our code as we did here.

function User(name, email) {
  this.name = name;
  this.email = email;
}

User.prototype.sayHello = function() {
  console.log(`Hello everybody, my name is ${this.name}`);
}

let sarah = new User('sarah', '[email protected]')

As you can see, we keep the assignment of properties that point to data inside the function. This makes sense, as these pieces of data are different for each object. However we move the assignment of properties that point to functions outside of constructor function and onto the constructor's prototype. This is because unlike the properties pointing to data, these methods are identical between instances of the same constructor.

Summary

In this section, we saw how we can use prototypes to avoid redeclaring identical functions. We saw that even though we are only declaring the function one time, with the use of a prototype each constructed object has access to the functions defined on its constructor's prototype.

Does this need an update?https

Please open a GitHub issue or pull-request. Provide a detailed description that explains the issue you have found or the change you are proposing. Then "@" mention your instructor on the issue or pull-request, and send them a link via Connect.

PHRG Using Prototypes

phrg-js-object-oriented-prototypes-readme's People

Contributors

annjohn avatar aviflombaum avatar blake41 avatar connorgallopo avatar crwhitesides avatar eaylward8 avatar garettarrowood avatar gj avatar jeffkatzy avatar jmburges avatar scottcreynolds avatar victhevenot avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.