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/03-code-quality/04-ninja-code/article.md
+17-17Lines changed: 17 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ For instance, take a look at this ternary operator `'?'`:
23
23
i = i ? i <0?Math.max(0, len + i) : i :0;
24
24
```
25
25
26
-
Cool, right? If you write like that, the developer who comes across this line and tries to understand what is the value of `i`will probably have a merry time. Then come to you, seeking for an answer.
26
+
Cool, right? If you write like that, the developer who comes across this line and tries to understand what is the value of `i`is going to have a merry time. Then come to you, seeking for an answer.
27
27
28
28
Tell him that shorter is always better. Initiate him into the paths of ninja.
29
29
@@ -36,11 +36,11 @@ completed.
36
36
37
37
Another way to code faster (and much worse!) is to use single-letter variable names everywhere. Like `a`, `b` or `c`.
38
38
39
-
A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using the "search" of the editor. And even if someone does, he won't be able to "decipher" what the name `a` or `b` means.
39
+
A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using "search" of the editor. And even if someone does, he won't be able to "decipher" what the name `a` or `b` means.
40
40
41
41
...But there's an exception. A real ninja will never use `i` as the counter in a `"for"` loop. Anywhere, but not here. Look around, there are so much more exotic letters. For instance, `x` or `y`.
42
42
43
-
An exotic variable as a loop counter is especially cool if the loop body takes 1-2 pages (make it longer if you can). Then if someone looks deep inside the loop, he won't be able to figure out fast that the variable is the loop counter.
43
+
An exotic variable as a loop counter is especially cool if the loop body takes 1-2 pages (make it longer if you can). Then if someone looks deep inside the loop, he won't be able to figure out fast that the variable named `x`is the loop counter.
44
44
45
45
## Use abbreviations
46
46
@@ -53,7 +53,7 @@ Like this:
53
53
-`browser` -> `brsr`.
54
54
- ...etc
55
55
56
-
Only the one with a truly good intuition will be able to understand all such names. Try to shorten everything. Only a worthy person will be able to uphold the development of such code.
56
+
Only the one with a truly good intuition will be able to understand such names. Try to shorten everything. Only a worthy person should be able to uphold the development of your code.
57
57
58
58
## Soar high. Be abstract.
59
59
@@ -68,15 +68,15 @@ While choosing a name try to use the most abstract word. Like `obj`, `data`, `va
68
68
69
69
-**The ideal name for a variable is `data`.** Use it everywhere where you can. Indeed, every variable holds *data*, right?
70
70
71
-
...But what to do if `data` is already taken? Try `value`, it's also universal. A variable always has a *value*, correct?
71
+
...But what to do if `data` is already taken? Try `value`, it's also universal. After all, a variable eventually gets a *value*.
72
72
73
73
-**Name the variable by its type: `str`, `num`...**
74
74
75
-
...But will that make the code worse? Actually, yes!
75
+
Give them a try. A young ninja may wonder -- do such names make the code worse? Actually, yes!
76
76
77
77
From one hand, the variable name still means something. It says what's inside the variable: a string, a number or something else. But when an outsider tries to understand the code -- he'll be surprised to see that there's actually no information at all!
78
78
79
-
Actually, the value type is easy to see by debugging. But what's the meaning of the variable? Which string/number it stores? There's just no way to figure out without a good meditation!
79
+
Indeed, the value type is easy to find out by debugging. But what's the meaning of the variable? Which string/number it stores? There's just no way to figure out without a good meditation!
80
80
81
81
-**...But what if there are no more such names?** Just add a letter: `item1, item2, elem5, data1`...
82
82
@@ -97,19 +97,19 @@ A quick read of such code becomes impossible. And when there's a typo... Ummm...
97
97
The hardest thing of all is to find a black cat in a dark room, especially if there is no cat.
98
98
```
99
99
100
-
Use*similar* names for *same* things, that makes life more interesting and shows your creativity to the public.
100
+
Using*similar* names for *same* things makes life more interesting and shows your creativity to the public.
101
101
102
-
For instance, the function prefixes. If a function shows a message on the screen -- start it with `display…`, like `displayMessage`. And then if another function shows something else, like a user name, start it with `show…` (like `showName`).
102
+
For instance, consider function prefixes. If a function shows a message on the screen -- start it with `display…`, like `displayMessage`. And then if another function shows on the screen something else, like a user name, start it with `show…` (like `showName`).
103
103
104
104
Insinuate that there's a subtle difference difference between such functions, while there is none.
105
105
106
-
Make a pact with fellow ninjas of the team: if John starts "showing" functions with `display...` in his code, then Peter could use `render..`, and Ann -- `paint...`. Note how more interesting and diverse the code became.
106
+
Make a pact with fellow ninjas of the team: if John starts "showing" functions with `display...` in his code, then Peter could use `render..`, and Ann -- `paint...`. Note how much more interesting and diverse the code became.
107
107
108
108
...And now the hat trick!
109
109
110
110
For two functions with important differences -- use the same prefix!
111
111
112
-
For instance, the function `printPage(page)` will use a printer. And the function `printText(text)` will put the text on-screen. Let an unfamiliar reader think well over things: "Where does `printMessage(message)` put the message? To a printer or on the screen?". To make it really shine, `printMessage(message)` should output it in the new window!
112
+
For instance, the function `printPage(page)` will use a printer. And the function `printText(text)` will put the text on-screen. Let an unfamiliar reader think well over similarly named function `printMessage`: "Where does it put the message? To a printer or on the screen?". To make it really shine, `printMessage(message)` should output it in the new window!
113
113
114
114
## Reuse names
115
115
@@ -126,7 +126,7 @@ Instead, reuse existing names. Just write new values into them.
126
126
127
127
In a function try to use only variables passed as parameters.
128
128
129
-
That would make it impossible to identify what's exactly in the variable *now*. And also where it comes from. A person with weak intuition would have to analyze the code line-by-line and track the changes through every code branch.
129
+
That would make it really hard to identify what's exactly in the variable *now*. And also where it comes from. A person with weak intuition would have to analyze the code line-by-line and track the changes through every code branch.
130
130
131
131
**An advanced variant of the approach is to covertly (!) replace the value with something alike in the middle of a loop or a function.**
132
132
@@ -148,7 +148,7 @@ Deadly effective even against an experienced ninja. Seen in code regularly.
148
148
149
149
## Underscores for fun
150
150
151
-
Put underscores `_` and `__` before variable names. Like `_name` or `__value`. It would be great if only you know their meaning. Or, better, without meaning at all.
151
+
Put underscores `_` and `__` before variable names. Like `_name` or `__value`. It would be great if only you knew their meaning. Or, better, add them just for fun, without particular meaning at all. Or different meanings in different places.
152
152
153
153
You kill two rabbits with one shot. First, the code becomes longer and less readable, and the second, a fellow developer may spend a long time trying to figure out what the underscores mean.
154
154
@@ -189,13 +189,13 @@ Then he'll try to work with `user` it assuming that it's the external variable,
189
189
190
190
## Side-effects everywhere!
191
191
192
-
There are functions that look like they don't change anything. Like `isReady()`, `checkPermission()`, `findTags()`... They are assumed to carry out calculations, find and return the data, without changing anything outside of them. That's called "no side-effects".
192
+
There are functions that look like they don't change anything. Like `isReady()`, `checkPermission()`, `findTags()`... They are assumed to carry out calculations, find and return the data, without changing anything outside of them. In other words, without "side-effects".
193
193
194
-
**A really beautiful trick -- is to add a "useful" action to them, besides the main task.**
194
+
**A really beautiful trick is to add a "useful" action to them, besides the main task.**
195
195
196
-
The expression of dazed surprise on the face of your colleague when he see a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.
196
+
The expression of dazed surprise on the face of your colleague when he sees a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.
197
197
198
-
**Another way to surprise -- is to return a non-standard result.**
198
+
**Another way to surprise is to return a non-standard result.**
199
199
200
200
Show your original thinking! Let the call of `checkPermission` return not `true/false`, but a complex object with the results of the check.
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/03-symbol/article.md
+14-6Lines changed: 14 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -252,11 +252,19 @@ Other symbols will also become familiar when we study the corresponding language
252
252
253
253
## Summary
254
254
255
-
- Symbol is a primitive type for unique identifiers.
256
-
- Symbols are created with `Symbol(name)` call.
257
-
- Symbols are useful if we want to create a field that only those who know the symbol can access.
258
-
- Symbols don't appear in `for..in` loops.
259
-
- Symbols created with `Symbol(name)` are always different, even if they have the same name. If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(name)` returns (creates if needed) a global symbol with the given name. Multiple calls return the same symbol.
260
-
- There are system symbols used by JavaScript and accessible as `Symbol.*`. We can use them to alter some built-in behaviors.
255
+
`Symbol` is a primitive type for unique identifiers.
256
+
257
+
Symbols are created with `Symbol(name)` call.
258
+
259
+
Symbols are always different values, even if they have the same name. If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(name)` returns (creates if needed) a global symbol with the given name. Multiple calls of `Symfol.for` return exactly the same symbol.
260
+
261
+
Symbols have two main use cases:
262
+
263
+
1. "Hidden" object properties.
264
+
If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be occasionally listed. Also it won't be accessed directly, because another script does not have our symbol, so it will not occasionally intervene into its actions.
265
+
266
+
So we can "covertly" hide something into objects that we need, but others should not see, using symbolic properties.
267
+
268
+
2. There are many system symbols used by JavaScript and accessible as `Symbol.*`. We can use them to alter some built-in behaviors. For instance, later in the tutorial we'll use `Symbol.iterator` for [iterables](info:iterable), `Symbol.toPrimitive` to setup [object-to-primitive conversion](info:object-toprimitive) and so on.
261
269
262
270
Technically, symbols are not 100% hidden. There is a build-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. So they are not really hidden. But most libraries, built-in methods and syntax constructs adhere to a common agreement that they are. And the one who explicitly calls the aforementioned methods probably understands well what he's doing.
0 commit comments