Skip to content

Commit a7c00e1

Browse files
committed
up
1 parent 6c9c221 commit a7c00e1

File tree

14 files changed

+248
-240
lines changed

14 files changed

+248
-240
lines changed

1-js/03-code-quality/02-coding-style/article.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,6 @@ Also you can see [the manual](http://eslint.org/docs/user-guide/getting-started)
307307

308308
All syntax rules from this chapter and the style guides aim to increase readability.
309309

310-
When you read style guides and think about "how to write better", the sole criterion is "does the code become more readable and easier to understand?" Then it becomes easier to pick up the best practices for that. Or even abandon some in cases when you see that they don't help.
310+
All of them are debatable.
311+
312+
When we think about "how to write better?", the sole criterion is "what makes the code more readable and easier to understand? what helps to evade errors?" The answer helps to pick up best practices. And maybe to abandon some in case if they don't contribute.
25.1 KB
Loading
62.6 KB
Loading
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
The answer has two parts.
2+
3+
The first, an easy one is that the inheriting class needs to call `super()` in the constructor. Otherwise `"this"` won't be "defined".
4+
5+
So here's the fix:
6+
7+
```js run
8+
class Rabbit extends Object {
9+
constructor(name) {
10+
*!*
11+
super(); // need to call the parent constructor when inheriting
12+
*/!*
13+
this.name = name;
14+
}
15+
}
16+
17+
let rabbit = new Rabbit("Rab");
18+
19+
alert( rabbit.hasOwnProperty('name') ); // true
20+
```
21+
22+
But that's not all yet.
23+
24+
Even after the fix, there's still important difference in `"class Rabbit extends Object"` versus `class Rabbit`.
25+
26+
As we know, the "extends" syntax sets up two prototypes:
27+
28+
1. Between `"prototype"` of the constructor functions (for methods).
29+
2. Between the constructor functions itself (for static methods).
30+
31+
In our case, for `class Rabbit extends Object` it means:
32+
33+
```js run
34+
class Rabbit extends Object {}
35+
36+
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
37+
alert( Rabbit.__proto__ === Object ); // (2) true
38+
```
39+
40+
So we can access static methods of `Object` via `Rabbit`, like this:
41+
42+
```js run
43+
class Rabbit extends Object {}
44+
45+
*!*
46+
// normally we call Object.getOwnPropertyNames
47+
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b
48+
*/!*
49+
```
50+
51+
And if we don't use `extends`, then `class Rabbit` does not get the second reference.
52+
53+
Please compare with it:
54+
55+
```js run
56+
class Rabbit {}
57+
58+
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
59+
alert( Rabbit.__proto__ === Object ); // (2) false (!)
60+
61+
*!*
62+
// error, no such function in Rabbit
63+
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
64+
*/!*
65+
```
66+
67+
For the simple `class Rabbit`, the `Rabbit` function has the same prototype
68+
69+
```js run
70+
class Rabbit {}
71+
72+
// instead of (2) that's correct for Rabbit (just like any function):
73+
alert( Rabbit.__proto__ === Function.prototype );
74+
```
75+
76+
By the way, `Function.prototype` has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`.
77+
78+
Here's the picture:
79+
80+
![](rabbit-extends-object.png)
81+
82+
So, to put it short, there are two differences:
83+
84+
| class Rabbit | class Rabbit extends Object |
85+
|--------------|------------------------------|
86+
| -- | needs to call `super()` in constructor |
87+
| `Rabbit.__proto__ === Function.prototype` | `Rabbit.__proto__ === Object` |
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
importance: 5
2+
3+
---
4+
5+
# Class extends Object?
6+
7+
As we know, all objects normally inherit from `Object.prototype` and get access to "generic" object methods.
8+
9+
Like demonstrated here:
10+
11+
```js run
12+
class Rabbit {
13+
constructor(name) {
14+
this.name = name;
15+
}
16+
}
17+
18+
let rabbit = new Rabbit("Rab");
19+
20+
*!*
21+
// hasOwnProperty method is from Object.prototype
22+
// rabbit.__proto__ === Object.prototype
23+
alert( rabbit.hasOwnProperty('name') ); // true
24+
*/!*
25+
```
26+
27+
So, is it correct to say that `"class Rabbit extends Object"` does exactly the same as `"class Rabbit"`, or not?
28+
29+
Will it work?
30+
31+
```js
32+
class Rabbit extends Object {
33+
constructor(name) {
34+
this.name = name;
35+
}
36+
}
37+
38+
let rabbit = new Rabbit("Rab");
39+
40+
alert( rabbit.hasOwnProperty('name') ); // true
41+
```
42+
43+
If it won't please fix the code.

0 commit comments

Comments
 (0)