Just-Javascript-Reading-Notes
Just-Javascript-Reading-Notes copied to clipboard
[Just JavaScript] 09. Prototypes
09. Prototypes
Prototypes
let human = {
teeth: 32
};
let gwen = {
age: 19
};
According to the rules we’ve learned, if we read it, we get undefined:
console.log(gwen.teeth); // undefined
But we can modify the codes like this:
let human = {
teeth: 32
};
let gwen = {
// We added this line:
__proto__: human,
age: 19
};
Prototypes in Action
Thanks to that __proto__
: human line, the answer is different now:
let human = {
teeth: 32
};
let gwen = {
// "Look for other properties here"
__proto__: human,
age: 19
};
console.log(gwen.teeth); // 32
The Prototype Chain
A prototype isn’t a special “thing” in JavaScript. A prototype is more like a relationship. An object may point at another object as its prototype.
let mammal = {
brainy: true,
};
let human = {
__proto__: mammal,
teeth: 32
};
let gwen = {
__proto__: human,
age: 19
};
console.log(gwen.brainy); // true
This sequence of objects to “visit” is known as our object’s prototype chain.
Shadowing
let human = {
teeth: 32
};
let gwen = {
__proto__: human,
// This object has its own teeth property:
teeth: 31
};
console.log(human.teeth); // 32
console.log(gwen.teeth); // 31
In other words, once we find our property, we stop the search.
Assignment
Consider this example:
let human = {
teeth: 32
};
let gwen = {
__proto__: human,
// Note: no own teeth property
};
gwen.teeth = 31;
console.log(human.teeth); // ?
console.log(gwen.teeth); // ?
Before the assignment, both expressions result in 32:
Then we need to execute this assignment:
gwen.teeth = 31;
So gwen.teeth = 31
creates a new own property called teeth on the object that gwen points at. It doesn’t have any effect on the prototype:
The result is:
console.log(human.teeth); // 32
console.log(gwen.teeth); // 31
When we read a property that doesn’t exist on our object, then we’ll keep looking for it on the prototype chain. If we don’t find it, we get undefined. But when we write a property that doesn’t exist on our object, that will create that property on our object. Generally saying, prototypes will not play a role.
The Object Prototype
let obj = {};
console.log(obj.__proto__); // Play with it!
Surprisingly, obj.__proto__
is not null or undefined! Instead, you’ll see a curious object with a bunch of properties, including hasOwnProperty.
We’re going to call that special object the Object Prototype:
At first, this might be a bit mindblowing. Let that sink in. All this time we were thinking that {} creates an “empty” object. But it’s not so empty, after all! It has a hidden __proto__
wire that points at the Object Prototype by default.
let human = {
teeth: 32
};
console.log(human.hasOwnProperty); // (function)
console.log(human.toString); // // (function)
These “built-in” properties are nothing more than normal properties that exist on the Object Prototype. Our object’s prototype is the Object Prototype, which is why we can access them. (Their implementations are inside the JS engine.)
An Object with No Prototype
let weirdo = {
__proto__: null
};
This will produce an object that truly doesn’t have a prototype, at all. As a result, it doesn’t even have built-in object methods:
console.log(weirdo.hasOwnProperty); // undefined
console.log(weirdo.toString); // undefined
Polluting the Prototype
let obj = {};
obj.__proto__.smell = 'banana';
We mutated the Object Prototype by adding a smell property to it. As a result, both detectives now appear to be using a banana-flavored perfume:
console.log(sherlock.smell); // "banana"
console.log(watson.smell); // "banana"
Mutating a shared prototype like we just did is called prototype pollution.
Recap
- When reading obj.prop, if obj doesn’t have a prop property, JavaScript will look for
obj.__proto__.prop
, then it will look forobj.__proto__.__proto__.prop
, and so on, until it either finds our property or reaches the end of the prototype chain. - When writing to obj.prop, JavaScript will usually write to the object directly instead of traversing the prototype chain.
- We can use obj.hasOwnProperty('prop') to determine whether our object has an own property called prop. In other words, it means there is a property wire called prop attached to that object directly.
- We can “pollute” a prototype shared by many objects by mutating it. We can even do this to the Object Prototype — the default prototype for {} objects! But we shouldn’t do that unless we’re pranking our colleagues.
- You probably won’t use prototypes much directly in practice. However, they are fundamental to how JavaScript objects work, so it is handy to understand their underlying mechanics. Some advanced JavaScript features, including classes, can be expressed in terms of prototypes.
So where is the end of the prototype chain.
So where is the end of the prototype chain.
@mdAliMaaz [What is the end of prototype chain in JavaScript -- null or Object.prototype? This may helps u
Hi, great work first of all. I can see there's 9 chapters altogether and wonder if there would be more to come. Thanks :)
Hi, great work first of all. I can see there's 9 chapters altogether and wonder if there would be more to come. Thanks :)
Hi, great work first of all. I can see there's 9 chapters altogether and wonder if there would be more to come. Thanks :)
Hi @jacinyan I check the Jast Javascript and there is no more articles