Blog

Prototype, new, Scope, this, and Classes Intro
Posted on September 16, 2020 in JavaScript by Matt Jennings

Way to use a prototype (__proto__ property on an object):

function userCreator(new, score) {
  const newUser = Object.create(userFunctionStore);
  newUser.name = name;
  newUser.score = score;
  return newUser;
}

// When userFunctionStore is passed into
// Object.create() inside the userCreator function
// and then invoked the userFunctionStore object is
// added to the __proto__ property
const userFunctionStore = {
  increment: function() {
    this.score++;
  },
  login: function() {
    console.log("You're loggedin");
  }
};

const user1 = userCreator("Phil", 4);
user1.increment();
console.log(user1.score); // 5

new Keyword

When we call the constructor function with new in front we automate 2 things:

  1. Create a new object
  2. Return that new object

functions are both objects and functions

// When declaring a function I
// get a prototype function
function multiplyBy2(num) {
  return num * 2;
}

multiplyBy2.stored = 5;
multipleBy2(3); // 6

multiplyBy2.stored; // 5
multiplyBy2.prototype // {}

Way to Link a Method to an Object ONLY when the Object is Instantiated

function UserCreator(name, score) {
  this.name = name;
  this.score = score;
}

UserCreator.prototype.increment = function() {
  this.score++;
};

UserCreator.prototype.login = function() {
  console.log('login');
};

const user1 = new UserCreator('Eva', 9);

user1.increment();

user1.score; // 10

// The __proto__ property of the user1 object is a property
// that maps to the prototype property of contructor function (UserCreator) 
// when using the keyword new to create a new object in front of the constructor function.
// In other words:
console.log(user1.__proto__ === UserCreator.prototype); // true

Calling a Method on an Object and the Assignment of this

When a method is called on an object, then the assignment of this refers to the object on the left side of the dot, like user1 in user1.increment(); per the code below:

function UserCreator(name, score) { 
  this.name = name; 
  this.score = score; 
} 

UserCreator.prototype.increment = function() { 
  this.score++; 
}; 

const user1 = new UserCreator('Eva', 9); 

// the "this" in the increment method refers to the "user1" object
user1.increment(); 

user1.score; // 10

We Need to Introduce Arrow Functions which binds this lexically

function UserCreator(name, score) { 
  this.name = name; 
  this.score = score; 
} 

UserCreator.prototype.increment = function() { 
  // The "this" inside in the anonymous function
  // assigned to the "add1" variable
  // is lexically scoped or identical 
  // to the "this" inside the "increment" function
  // but not inside another child function
  const add1 = () => { this.score++; };
  add1();
}; 

const user1 = new UserCreator('Eva', 9); 

// the "this" in the increment method refers to the "user1" object
user1.increment(); 

user1.score; // 10

Class “Syntactic Sugar”

Any functions listed inside a class are automatically added to an assigned object’s __proto__ property.  This assigned object is created via const user1 = new UserCreator("Eva", 9); below.

Then the user1 object’s __proto__ property has the increment and login methods inside this object and they are linked to the UserCreator  prototype property, which also has the increment and login methods inside this object.

The constructor method can only be called once in a class and when an object is instantiated (like user1 below) the arguments passed into the UserCreator invoked class ("Eva" and 9 below) are added to user1 object as properties, and NOT on the user1 __proto__ property.

class UserCreator() {
  constructor(name, score) {
    this.name = name;
    this.score = score;
  }
  increment() {
    this.score++;
  }
  login() {
    console.log("login");
  }
}

const user1 = new UserCreator("Eva", 9);

user1.increment();

user1.score; // 10

 

Leave a Reply