diff --git a/_posts/2024-04-25-js-intermediate-07-proto-prototype-objects.md b/_posts/2024-04-25-js-intermediate-07-proto-prototype-objects.md index 47cb4f376dd..33a8be94009 100644 --- a/_posts/2024-04-25-js-intermediate-07-proto-prototype-objects.md +++ b/_posts/2024-04-25-js-intermediate-07-proto-prototype-objects.md @@ -1,5 +1,5 @@ --- -title: Javascript Intermediate 0 +title: Javascript Intermediate 7 - Differences between __proto__ and .prototype on Objects tags: javascript, programming, coding, nodejs, syntax article_header: type: cover @@ -7,7 +7,150 @@ article_header: src: images/js-intermediate-dog-02.png --- -# Title + +In its most basic form __proto__ is a built-in property in all objects in JS , that you set to other object so it inherits its properties. +The firstObject will inherit secondObjects properties , and the properties of the secondObject.__proto__ object and so on. + +``` +let tangible = { + isTouchable: true +} +let resource = { + hasUtility: true, + __proto__: tangible +} + +let food = { + isEdible: true +} +food.__proto__ = resource; + +console.log(food); // { isEdible: true } +console.log(food.hasUtility); // true +console.log(food.isTouchable); // true +``` + +In JS all the functions can work as Constructors using the new keyword. If instanciated an Object via a constructor function , then the __proto__ of the instance will be identical to its Constructor function .prototype property + +``` +function Food () { + this.isEdible = true; +} + +var pasta = new Food(); + +console.log(Food.prototype === pasta.__proto__); // true +``` + +Remember that non enumerable properties wont be listed , which happens with are almost all the properties of the built in objects, so if you want to see them use the following method. +`Object.getOwnPropertyDescriptors();` +Even better if you make an array +`Object.keys(Object.getOwnPropertyDescriptors());` + +__proto__ has some limitations. + + - The references cant go in circles. JavaScript will throw an error if we try to assign __proto__ in a circle (if for instance food is at the same time __proto__ of tangible) + - The value of __proto__ can be either an object or null. Other types are ignored. + - __proto__ can only be one object !! + - __proto__ is a historical getter/setter of [[Prototype]] , which is the actual property + + + - Prototyped accessed properies are fallback properties in the sense that (On data properties) + - Attempting to Delete them in the child object has no effect (cause there is in fact no such as property) + - Attempting to Write them on the child object will create an actual property on the child object leaving untouched the parents property + +``` +let resource = { + hasUtility: true, + hasHumanLabour: true +} + +let food = { + isEdible: true, + __proto__: resource +} + +delete food.hasUtility ; +console.log(resource.hasUtility); // true +console.log(food.hasUtility); // true + +food.hasHumanLabour = false; +console.log(resource.hasHumanLabour); // true +console.log(food.hasHumanLabour); // false +``` + +(On Accessor properties) such as getters and setters the behaviour is derived of what it happens under the hood. + - Attempting to Delete them in the child object has no effect + - Attempting to write or read them will work as normal (because they are calling the function anyways) + + +``` +let resource = { + hasUtility: true, + price: 0, + set setPrice(price) { + this.price = price; + }, + get getPrice() { + return this.price; + } +} + +let food = { + isEdible: true, + __proto__: resource +} + + +delete food.setPrice ; +food.setPrice = 20; +console.log(food.getPrice); // 20 +``` + +Last clarification: this keyword will correspond to the object calling it + +``` +let resource = { + hasUtility: true, + name: '', + set setName(name) { + this.name = name; + }, + get getName() { + return this.name; + } +} + +let food = { + isEdible: true, + __proto__: resource +} + + +food.setName = 'Rabioli'; +console.log(food.getName); // Rabioli +``` + + You can demostrate that an object is prototype of some other object with +`Object.prototype.isPrototypeOf(obj)` +For oposition `instanceof` wont work the other way around as it is not comparing object to object but object to Constructor + + +``` +let resource = { + hasUtility: true, +} + +let food = { + isEdible: true, + __proto__: resource +} + + +console.log(resource.isPrototypeOf(food)); // True +console.log(food instanceof resource); // Type Error (right hand side not-callable) +``` + ## Javascript Intermediate tutorials @@ -31,8 +174,3 @@ As main source of information I list the following. - [Mdn Web Docs Web API](https://developer.mozilla.org/en-US/docs/Web/API) Which I comfortably read from my terminal via [vim-dan](https://github.com/freddieventura/vim-dan) - -## Reference sources - -1. []() -2. []()