`

Prototypical Inheritance

Inheritance is the behavior in any programming language where a child(object/function in JavaScript) apart from having it’s own properties and behavior receives these from its parent as well. In JavaScript when it is achieved using prototype property of a function which is called Prototype inheritance.

When a function is declared, JavaScript automatically attaches a blank prototype property to it with value as empty object i.e., {} .

When an object is created, JavaScript by default attaches a __proto__ property to it with value as empty object i.e., {}. Now if the object is created using constructor function, JavaScript copies the reference of prototype property of the function to __proto__ property of the object.

function.prototype === object.____proto____  // Output: true
// Prototype inheritance example with inbuilt Object constructor function

let obj1 = {a: 2}
Object.prototype = obj1.____proto____ // Output : true
// Prototype inheritance example with inbuilt Array constructor function

var arr = [1, 2, 3];
console.log(Array.prototype === arr.____proto___) // Output : true

callBackFunction1 = (value, index)=> {
    console.log(index)
    console.log(value)
}
arr.forEach(callBackFunction1)

Array.prototype.forEachCustom = function(callBackFunction) {
    console.log(this);
    for(let i = 0; i< this.length; i++) {
        callBackFunction(this[i], i)
    }
}
// Prototype inheritance example with inbuilt Array function

var arr = [1, 2, 3];
console.log(Array.prototype === arr.____proto___) // Output : true

multiplyByTwoCallback = (value)=> {
    return value * 2
}

arr.map(multiplyByTwoCallback)

Array.prototype.mapCustom = function(callBackFunction) {
    let updatedArray = []
    for(let i = 0; i< this.length; i++) {
        let returnValue = callBackFunction(this[i])
        updatedArray.push(returnValue)
    }

    return updatedArray
}
arr.map(multiplyByTwoCallback)
arr.forEachCustom(callBackFunction1)
// Prototype inheritance example with custom constructor function

function constructorMovie (movieName, releaseYear) {
    this.name = name;
    this.releaseYear =  releaseYear;
}
let movie1 = new constructorMovie("movie1", 2015);
constructorMovie.prototype // Output: {} empty object
movie1.__proto__ === constructorMovie.prototype // Output: true

// JavaScript allow new properties to be added to a function constructorMovie
constructorMovie.newProp1 = "prop1Value"
console.log(movie1.newProp1) // Output: undefined

constructorMovie.newProp1 = "prop1Value"
console.log(movie1.newProp1) // Output: undefined
function firstName() {
    this.firstName = "name"
}

function name() extends firstName {
    this.firstName = "name"
}