Revision:
Whenever we create a function using JavaScript, the JavaScript engine adds a prototype property inside that function. Prototype property is basically an object (also known as Prototype object), where we can attach "methods" and "properties", which enables all the other objects to inherit these methods and properties.
Examples
<div> <p id="proto1"></p> </div> <script> // constructor function function People(){ this.name = "Oscar"; this.age = 40; } console.log(People.prototype); // {...} document.getElementById("proto1").innerHTML = (People.prototype); </script>
All JavaScript objects inherit properties and methods from a prototype:
Date objects inherit from Date.prototype
Array objects inherit from Array.prototype
Person objects inherit from Person.prototype
Examples
<div> <p id="proto2"></p> <p id="proto3"></p> <p id="proto4"></p> </div> <script> // constructor function function Person1 () { this.name = 'John', this.age = 23 } // creating objects const person1 = new Person1(); const person2 = new Person1(); // adding property to constructor function Person1.prototype.gender = 'male'; // prototype value of Person console.log(Person1.prototype); document.getElementById("proto2"). innerHTML = (Person1.prototype); // inheriting the property from prototype console.log(person1.gender); document.getElementById("proto3"). innerHTML = person1.gender; console.log(person2.gender); document.getElementById("proto4"). innerHTML = person2.gender; </script>
The Object.prototype is on the top of the prototype inheritance chain: Date objects, Array objects, and Person objects inherit from Object.prototype.
Sometimes you want to add new properties (or methods) to all existing objects of a given type. Sometimes you want to add new properties (or methods) to an object constructor.
The JavaScript prototype property allows you to add new properties and new methods to object constructors.
Examples
<div> <p id="proto5"></p><br> </div> <script> // constructor function function Person2 () { this.name = 'Oscar', this.age = 33 } // creating objects const person3= new Person2(); const person4 = new Person2(); // adding a method to the constructor function Person2.prototype.greet = function() { console.log('hello' + ' ' + this.name); document.getElementById("proto5").innerHTML += ('hello' + ' ' + this.name + "<br>"); } person3.greet(); // hello Oscar person4.greet(); // hello Oscar </script>
!!! Only modify your own prototypes. Never modify the prototypes of standard JavaScript objects.
JavaScript provides different ways to set the prototype of an object ourselves. It is not recommended to assign a new object to the __proto__ property directly. It's not well supported by all browsers.
Instead of reading an object's prototype via the "__proto__ property", "Object.getPrototypeOf" can also be used.
You can pass another object to "Object.create" to add specific instance properties to the object being created.
Syntax" Object.create(proto) or Object.create(proto, propertiesObject)
Parameters:
proto : the object which should be the prototype of the newly-created object.;
propertiesObject : optional; if specified and not undefined, an object whose enumerable own properties specify property descriptors to be added to the newly-created object, with the corresponding property names. These properties correspond to the second argument of Object.defineProperties().
Examples
<div> <p id="proto6"></p> </div> <script> const person = { isHuman: false, printIntroduction: function() { console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`); document.getElementById("proto6").innerHTML = (`My name is ${this.name}. Am I human? ${this.isHuman}`); } }; const me = Object.create(person); me.name = 'Oscar'; // "name" is a property set on "me", but not on "person" me.isHuman = true; // Inherited properties can be overwritten me.printIntroduction(); // Expected output: "My name is Oscar. Am I human? true" </script>
Any function can be used as a constructor but by convention, constructor function names start with a capital letter.
To create an instance of a constructor function, you use the "new" keyword with the function invocation. When the "new" keyword is used, JavaScript assigns the keyword "this" implicitly to the new object being created. So we can use "this" to refer to the object being created.
Examples
<div> <p id="prop2"></p> </div> <script> // Constructor function for Person objects function Person3(first, last, age, eye) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eye; } const myFather1 = new Person3("Oscar", "Peeters", 50, "blue"); document.getElementById("proto7").innerHTML = "My father is " + myFather1.age + "."; </script>
An object can have two types of members: instance members a.k.a its own members, and prototype members. JavaScript provides ways by which we can differentiate both.
For example, the hasOwnProperty(fieldName) asks the JavaScript engine if "fieldName" is an instance member of the object in question.
The in operator in JavaScript checks for both the instance and prototype members.
If a prototype value is changed, then all the new objects will have the changed property value. All the previously created objects will have the previous value.
Examples
<div> <p id="proto8"></p> <p id="proto9"></p> <p id="proto10"></p> </div> <script> // constructor function function Person4() { this.name = 'Sylvia' } // add a property Person4.prototype.age = 20; // creating an object const person5 = new Person4(); console.log(person5.age); // 20 document.getElementById("proto8").innerHTML = person5.age // changing the property value of prototype Person4.prototype = { age: 50 } // creating new object const person6 = new Person4(); console.log(person6.age); // 50 console.log(person5.age); // 20 document.getElementById("proto9").innerHTML = person6.age document.getElementById("proto10").innerHTML = person5.age </script>
If an object tries to access the same property that is in the constructor function and the prototype object, the object takes the property from the constructor function.
Examples
<div> <p id="proto8"></p> <p id="proto9"></p> <p id="proto10"></p> </div> <script> // constructor function function Person4() { this.name = 'Sylvia' } // add a property Person4.prototype.age = 20; // creating an object const person5 = new Person4(); console.log(person5.age); // 20 document.getElementById("proto8").innerHTML = person5.age // changing the property value of prototype Person4.prototype = { age: 50 } // creating new object const person6 = new Person4(); console.log(person6.age); // 50 console.log(person5.age); // 20 document.getElementById("proto9").innerHTML = person6.age document.getElementById("proto10").innerHTML = person5.age </script>
example
<div class="spec"> <p id="alpha"></p> <p id="beta"></p> <p id="gamma"></p> </div> <script> function Person(first, last, age, eye) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eye; } Person.prototype.nationality = "English"; Person.prototype.name = function() { return this.firstName + " " + this.lastName }; const myFather = new Person("Albert", "Einstein", 50, "blue"); const myMother = new Person("Marie", "Currie", 45, "green"); document.getElementById("alpha").innerHTML = "My father is " + myFather.age + ". My mother is " + myMother.age; document.getElementById("beta").innerHTML = "My father is " + myFather.name(); document.getElementById("gamma").innerHTML = "The nationality of my father is " + myFather.nationality; </script>
<div class="spec"> <p id="delta"></p> </div> <script> function User(name, email) { this.name = name; this.email = email; } User.prototype.sayHello = function() { document.getElementById("delta").innerHTML += `Hello everybody, my name is ${this.name} <br>`; }; let sarah = new User("Sarah", "[email protected]"); let lauren = new User("Lauren", "[email protected]"); sarah.sayHello(); lauren.sayHello(); </script>
let obj = {}; alert( obj ); // "[object Object]" ? let obj = {}; alert(obj.__proto__ === Object.prototype); // true alert(obj.toString === obj.__proto__.toString); //true alert(obj.toString === Object.prototype.toString); //true
let arr = [1, 2, 3]; // it inherits from Array.prototype? alert( arr.__proto__ === Array.prototype ); // true // then from Object.prototype? alert( arr.__proto__.__proto__ === Object.prototype ); // true // and null on the top. alert( arr.__proto__.__proto__.__proto__ ); // null