Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Just JavaScript] 09. Prototypes #9

Open
allenGKC opened this issue Jul 9, 2020 · 4 comments
Open

[Just JavaScript] 09. Prototypes #9

allenGKC opened this issue Jul 9, 2020 · 4 comments

Comments

@allenGKC
Copy link
Owner

allenGKC commented Jul 9, 2020

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 for obj.__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.
@mdAliMaaz
Copy link

So where is the end of the prototype chain.

@allenGKC
Copy link
Owner Author

allenGKC commented Dec 11, 2023

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

@jacinyan
Copy link

jacinyan commented Jun 3, 2024

Hi, great work first of all. I can see there's 9 chapters altogether and wonder if there would be more to come. Thanks :)

@allenGKC
Copy link
Owner Author

allenGKC commented Jun 5, 2024

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

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants