Constructor Function

Every function is a constructor function.

We use the new keyword to use a constructor function

Functions has a __proto_ property, but is also has the prototype property. They are different, the __proto__ is a prototype of the function object, every object in JS has a __proto__ property. But they also have a function prototype, normal object do not have this property, only functions has this property. This property changes behaviour of how the 'new' keyword works. _

Please note:

  • __proto__ is the object prototype which is used for named resolution.
  • The function prototype 'eg: Person.prototype' only exists on functions, and is used to set the object prototype of an object that created with the 'new' keyword.

Example:

function add(left, right) {
    console.log(left,right); 
}

add(1,2); -> 1 2

//But this can be used as a constructor function 
//It is not how its defined but how its used. 
//We use the new keyword to use a constructor function: 

var blegh = new add(1,2); //Valid to do

function Person(name) {
    this.name = name;
    this.sayHi = function() {
        console.log("Hey" + name); 
    }
}

//What do you think will happen: (not strict mode)
var person = Person("Ian"); 
console.log(person); -> undefined
person.sayHi(): -> Uncaught TypeError: Cannot read property 'sayHi' of undefined 
//This is getting executed under the global context. 
//If we don't supply a context to a function call, it gets the global context. 
//We could return an object to fix this, but we can use the 'new' keyword

//Fix, the new keyword does interesting thing: 
var person = new Person("nelson"); 
console.log(person); -> Nelson
person.sayHi(); -> Hey nelson
//Everytime we instantiate a new Person, we get a new instance of the sayHi() function - Not efficient
//Function has an object prototype __proto__ , but they also have function prototype prototype: Object
//Normal object do not have the function prototype property, only functions has this property. 
//This property is interesting because it changes behaviour of how the 'new' keyword works.

//Lets say that I want to manipulate every single person that instantiated with the 'new' keyword with that constructor function: 
//What i would do: 
Person.prototype.sayHi = function() { //This only creates one instance of the sayHI function 
    console.log("Hey" + this.name);   
}

//when using Person.prototype: 
//This person object does not have a property called sayHi(); 
person.hasOwnProperty('sayHi') -> false 
person.__proto__.hasOwnProperty("sayHi"); -> true 
//So there is a relationship between the function prototype and the object prototype __proto__

How does the 'new' keyword works?

//Will only do this if we use the 'new' keyword' 
function Person(name) {
    //JS INTERNALS
    var _this = {}; //JS creates a new object 
    _this.__proto__ = Person.prototype;  //It then sets the object protoype to the function prototype 

    //OUR FUNCTION
    _this.name = name; //It changes the context of the 'this' 

    //JS INTERNALS
    return _this; 
}

So when we call new Person(), basically what happens are these internals.
  1. First Javascript create a new Object before even invoking Person.
  2. It will bind that new object to the context or the this of the function, which is why the _this.name, _when we use the 'new' keyword, is an empty object, whereas this.name if we didn't use the 'new' keyword it would be the global context
  3. Then it sets the prototype of that newly created object (_this.__proto__) to the prototype property (Person.prototype) of the constructor function.
  4. After that it invokes the constructor function : functionPerson(name) {.....}
  5. Finally it returns the newly created object _this

Simulate the 'new' keyword:

function Person(name) {
    this.name = name;
}

Person.prototype.sayHi = function() { 
    console.log("Hey" + this.name);   
}

-------------------------------------------------
var personObject = {}; //JS creates a new object 
personObject.__proto__ = Person.prototype; //Set the object prototype of the personObject to the function prototype of the constructor function
Person.call(personObject, "Nelson"); //Then it invokes the constructor function but it changes the context of the 'this' 

personObject.sayHi(); -> Hey, Nelson

Another Example:

function Person(name) {
}

Person.prototype -> Object{} - its just an empty object, it does has a constructor property

So, every function has a prototype. 

Another example:

function add(left,right){
    return left + right;
}

add.prototype -> Returns empty object.

Return a value from a constructor function.

Example 1:

function add(left, right){
    return left + right;
}

var something = new add(1,2);
console.log(something); -> add { ... } - Not intended to be a constructor function, it is also returning value. 

We can apply the 'new' keyword to any function.  
-something is an object

It ignores the return value.

Example 2:

function Person(name) {
    this.name = name;
    return {//This will override the return value! (so person__proto__ == Person.prototype will be false) 
        firstName: name;
        otherProp: "stuff;
    };
}

var person = new Person("Nelson"); -> Object {firstName: "Nelson", otherProp: "stuff"}

//In the case of the add(left,right) when we did the new add(...), when we return a value (such as number)
//that is not a object from a constructor function, then it is going to override the object value with 
//the object that was created. 

//If however, our constructor function returns an object,

In the case of the add(left, right) when we did the new add(...), when we return a value (such as number) that is not a object from a constructor function, then it is going to override the object value with the object that was created.

If however, our constructor functions returns an object, the value thats return by 'new' is going to be the object that was returned.

results matching ""

    No results matching ""