Realationship between prototype and __proto__ in Javascript

Existence of prototype and proto

  • Every Object in Js(Javascript) has proto field but NO prototype
  • Every function has prototype field and since functions are objects also, It has proto field as well.
let obj = {};
console.log(obj.prototype); // prints undefined
console.log(obj.__proto__); // prints [Object: null prototype] {}

let myFunc = function () {};
console.log(myFunc.prototype); // prints {}
console.log(myFunc.__proto__); // prints {}

What's special about proto

  • Whatever field we will attach in the proto , it will be accessible in the original object. When Js tries to search for a property in the object and it doesn't find it, then it will search inside proto.
  • To check if the property is actually present inside object, we can make use of "hasOwnProperty"
let obj1 = { a: 1 };
console.log(obj1.a); // logs 1
console.log(obj1.b); // logs undefined
obj1.__proto__.b = 2;
console.log(obj1.b); // logs 2
console.log(obj1.hasOwnProperty("a")); // logs true
console.log(obj1.hasOwnProperty("b")); // logs false

What's special about prototype

  • As prototype field is only present in function, we can attach some property to this , and it will be accessible to all the instances of that will be created using new operator.
function myfinc1() {
  this.a = 1;
}

myfinc1.prototype.b = 2;

let obj1 = new myfinc1();
console.log(obj1.b); // prints 2

But, How did it work?

  • When obj1 was created using new operator, It now has proto field (since, its now an object).
  • What Js did was, while creating obj1, it made sure that obj1.proto points to the main function's prototype field i.e myfunc1.prototype.
  • Now, when we are trying to search for obj1.b, it will eventually be found inside 'proto'
  • So, If we make changes to proto field, it will reflect in prototype field as well. as both are pointing to the same object. That's why it is suggested to never work with 'proto' directly
console.log(obj1.__proto__ === myfinc1.prototype); // prints true
obj1.__proto__.c = 3; // attaching a new property to it
console.log(myfinc1.prototype.c); // prints 3, prototype got changed as well