-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Objects and Object Constructors: Clarify prototype inheritance and Object.setPrototypeOf()
usage
#29465
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of accidental line breaks have been added?
Single line breaks don't render any differently and new paragraphs need to be separated by a single blank line (i.e. double line break). So the bits you've changed, anything that should be in the same paragraph should be on the same line of text, and anything that should be a separate paragraph should have a single blank line separating them, as opposed to just a line break.
javascript/organizing_your_javascript_code/objects_and_object_constructors.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this @dekr1sh, apologies this slipped through the cracks. Since I'm back on the team, I can get this moving again. Please see below for some comments.
@@ -262,7 +262,7 @@ Note: | |||
|
|||
#### Recommended method for prototypal inheritance | |||
|
|||
Now, how do you utilize Prototypal Inheritance? What do you need to do to use it? Just as we use `Object.getPrototypeOf()` to 'get' or view the `prototype` of an object, we can use `Object.setPrototypeOf()` to 'set' or mutate it. Let's see how it works by adding a `Person` Object Constructor to the `Player` example, and making `Player` inherit from `Person`! | |||
Now, how do you utilize Prototypal Inheritance? What do you need to do to use it? Just as we use `Object.getPrototypeOf()` to 'get' or view the `prototype` of an object, we can use `Object.setPrototypeOf()` to 'set' or mutate it. Basically, using `Object.setPrototypeOf()` to set a prototype is same as setting the prototype using objects's `[[Prototype]]` or `__proto__` property. Let's see how it works by adding a `Person` Object Constructor to the `Player` example, and making `Player` inherit from `Person`! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit - some grammar but also it's technically not the exact same mechanism, but the suggested wording below keeps the same idea.
Now, how do you utilize Prototypal Inheritance? What do you need to do to use it? Just as we use `Object.getPrototypeOf()` to 'get' or view the `prototype` of an object, we can use `Object.setPrototypeOf()` to 'set' or mutate it. Basically, using `Object.setPrototypeOf()` to set a prototype is same as setting the prototype using objects's `[[Prototype]]` or `__proto__` property. Let's see how it works by adding a `Person` Object Constructor to the `Player` example, and making `Player` inherit from `Person`! | |
Now, how do you utilize Prototypal Inheritance? What do you need to do to use it? Just as we use `Object.getPrototypeOf()` to 'get' or view the `prototype` of an object, we can use `Object.setPrototypeOf()` to 'set' or mutate it. Basically, using `Object.setPrototypeOf()` to set a prototype is essentially the same as setting the object's `[[Prototype]]` or `__proto__` property. Let's see how it works by adding a `Person` Object Constructor to the `Player` example, and making `Player` inherit from `Person`! |
From the code, we can see that we've defined a `Person` from whom a `Player` inherits properties and functions, and that the created `Player` objects are able to access both the `.sayName` and the `.getMarker` functions, in spite of them being defined on two separate `prototype` objects! This is enabled by the use of the `Object.setPrototypeOf()` function. It takes two arguments - the first is the one which inherits and the second argument is the one which you want the first argument to inherit from. This ensures that the created `Player` objects are able to access the `.sayName` and `.getMarker` functions through their prototype chain. The same can also be achieved using: | ||
|
||
```javascript | ||
Player.prototype.__proto__ = Person.prototype | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I don't think we should include this change with the added code example. The docs are clear it does not advise using .__proto__
at all - this lesson only mentions it here and there since people will come across it elsewhere or by looking in devtools, but it's not intended for use anymore. Having this code block, IMHO, makes it feel like we're saying it's fine and just an alternative syntax if people prefer.
@@ -310,7 +314,7 @@ A warning... this doesn't work: | |||
Player.prototype = Person.prototype; | |||
``` | |||
|
|||
because it will set `Player.prototype` to directly refer to `Person.prototype` (i.e. not a copy), which could cause problems if you want to edit something in the future. Consider one more example: | |||
because both `Player.prototype` and `Person.prototype` become the exact same object in memory. This means any changes made to `Player.prototype` will also affect `Person.prototype`, which is not the intended behavior. Instead, we should set `Player.prototype` to inherit from `Person.prototype`, rather than making them the same object. Consider one more example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit for word flow
because both `Player.prototype` and `Person.prototype` become the exact same object in memory. This means any changes made to `Player.prototype` will also affect `Person.prototype`, which is not the intended behavior. Instead, we should set `Player.prototype` to inherit from `Person.prototype`, rather than making them the same object. Consider one more example: | |
because both `Player.prototype` and `Person.prototype` become the exact same object in memory. This means any changes made to `Player.prototype` will also affect `Person.prototype`, which is not the intended behavior. Instead, we should make `Player.prototype` inherit from `Person.prototype`, rather than making them the same object. Consider one more example: |
Because
This PR improves the clarity of prototype inheritance. It explains how
Object.setPrototypeOf()
is equivalent to setting__proto__
or[[Prototype]]
and why directly assigningPlayer.prototype = Person.prototype
is incorrect.This PR
Object.setPrototypeOf()
and how it relates to__proto__
/[[Prototype]]
.Player.prototype = Person.prototype
is incorrect and whyObject.setPrototypeOf()
should be used instead.Issue
Closes #28633
Additional Information
Pull Request Requirements
location of change: brief description of change
format, e.g.Intro to HTML and CSS lesson: Fix link text
Because
section summarizes the reason for this PRThis PR
section has a bullet point list describing the changes in this PRIssue
section