You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/04-prototype-methods/article.md
+4-3
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,7 @@ let rabbit = Object.create(animal);
26
26
*/!*
27
27
28
28
alert(rabbit.eats); // true
29
+
29
30
*!*
30
31
alert(Object.getPrototypeOf(rabbit) === animal); // get the prototype of rabbit
31
32
*/!*
@@ -78,7 +79,7 @@ As of now we have all these ways at our disposal.
78
79
79
80
Why was `__proto__` replaced by the functions `getPrototypeOf/setPrototypeOf`? That's an interesting question, requiring us to understand why `__proto__` is bad. Read on to get the answer.
80
81
81
-
```warn header="Don't reset`[[Prototype]]`unless the speed doesn't matter"
82
+
```warn header="Don't change`[[Prototype]]`on existing objects if speed matters"
82
83
Technically, we can get/set `[[Prototype]]` at any time. But usually we only set it once at the object creation time, and then do not modify: `rabbit` inherits from `animal`, and that is not going to change.
83
84
84
85
And JavaScript engines are highly optimized to that. Changing a prototype "on-the-fly" with `Object.setPrototypeOf` or `obj.__proto__=` is a very slow operation, it breaks internal optimizations for object property access operations. So evade it unless you know what you're doing, or JavaScript speed totally doesn't matter for you.
@@ -111,7 +112,7 @@ Here the consequences are not terrible. But in other cases, we may be assigning
111
112
112
113
What's worst -- usually developers do not think about such possibility at all. That makes such bugs hard to notice and even turn them into vulnerabilities, especially when JavaScript is used on server-side.
113
114
114
-
Unexpected things also may happen when accessing `toString`property -- that's a function by default, and other built-in properties.
115
+
Unexpected things also may happen when assigning to `toString` -- that's a function by default, and other built-in methods.
115
116
116
117
How to evade the problem?
117
118
@@ -160,7 +161,7 @@ alert(obj); // Error (no toString)
160
161
161
162
...But that's usually fine for associative arrays.
162
163
163
-
Please note that most object-related methods are `Object.something(...)`, like `Object.keys(obj)` -- they are not in the prototype, so they will keep working on such objects:
164
+
Note that most object-related methods are `Object.something(...)`, like `Object.keys(obj)` -- they are not in the prototype, so they will keep working on such objects:
Here's an example with a computed property in brackets `[...]`:
286
286
287
287
```js run
288
-
functionf() { return"sayHi"; }
289
-
290
288
classUser {
291
-
[f()]() {
289
+
290
+
*!*
291
+
['say'+'Hi']() {
292
+
*/!*
292
293
alert("Hello");
293
294
}
294
295
@@ -309,7 +310,9 @@ In the example above, `User` only had methods. Let's add a property:
309
310
310
311
```js run
311
312
classUser {
313
+
*!*
312
314
name ="Anonymous";
315
+
*/!*
313
316
314
317
sayHi() {
315
318
alert(`Hello, ${this.name}!`);
@@ -319,16 +322,15 @@ class User {
319
322
newUser().sayHi();
320
323
```
321
324
322
-
The property is not placed into `User.prototype`. Instead, it is created by `new`, separately for every object. So, the property will never be shared between different objects of the same class.
323
-
325
+
The property `name` is not placed into `User.prototype`. Instead, it is created by `new` before calling constructor, it's the property of the object itself.
324
326
325
327
## Summary
326
328
327
329
The basic class syntax looks like this:
328
330
329
331
```js
330
332
classMyClass {
331
-
prop = value; //field
333
+
prop = value; //property
332
334
333
335
constructor(...) { // constructor
334
336
// ...
@@ -339,7 +341,7 @@ class MyClass {
339
341
getsomething(...) {} // getter method
340
342
setsomething(...) {} // setter method
341
343
342
-
[Symbol.iterator]() {} // method with computed name/symbol name
344
+
[Symbol.iterator]() {} // method with computed name (symbol here)
So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`.
94
94
95
-
As we can recall from the chapter <info:native-prototypes>, JavaScript uses the same prototypal inheritance for build-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`, so dates have generic object methods.
95
+
As we can recall from the chapter <info:native-prototypes>, JavaScript uses prototypal inheritance for build-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`, so dates have generic object methods.
96
96
97
97
````smart header="Any expression is allowed after `extends`"
98
98
Class syntax allows to specify not just a class, but any expression after `extends`.
@@ -131,7 +131,6 @@ class Rabbit extends Animal {
131
131
}
132
132
```
133
133
134
-
135
134
...But usually we don't want to totally replace a parent method, but rather to build on top of it, tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
0 commit comments