Skip to content

Commit 1b858a0

Browse files
committed
fixes
1 parent 2ca9d97 commit 1b858a0

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

1-js/01-getting-started/2-manuals-specifications/article.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ The latest draft is at <https://tc39.es/ecma262/>.
1414

1515
To read about bleeding-edge features, that are not yet widely supported, see proposals at <https://github.com/tc39/proposals>.
1616

17-
1817
Also, if you're in developing for the browser, then there are other specs covered in the [second part](info:browser-environment) of the tutorial.
1918

2019
## Manuals

1-js/06-advanced-functions/04-var/article.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,19 @@ alert(test); // true, the variable lives after if
4545
*/!*
4646
```
4747

48-
If we used `let test` on the 2nd line, then it wouldn't be visible to `alert`. But `var` ignores code blocks, so we've got a global `test`.
48+
`var` ignores code blocks, so we've got a global variable `test`.
49+
50+
If we used `let test` instead of `var test`, then the variable would only be visible inside `if`:
51+
52+
```js run
53+
if (true) {
54+
let test = true; // use "let"
55+
}
56+
57+
*!*
58+
alert(test); // Error: test is not defined
59+
*/!*
60+
```
4961

5062
The same thing for loops: `var` cannot be block- or loop-local:
5163

@@ -76,7 +88,7 @@ alert(phrase); // Error: phrase is not defined (Check the Developer Console)
7688

7789
As we can see, `var` pierces through `if`, `for` or other code blocks. That's because a long time ago in JavaScript blocks had no Lexical Environments. And `var` is a remnant of that.
7890

79-
## "var" are processed at the function start
91+
## "var" declarations are processed at the function start
8092

8193
`var` declarations are processed when the function starts (or script starts for globals).
8294

@@ -178,11 +190,11 @@ In both examples above `alert` runs without an error, because the variable `phra
178190

179191
## Summary
180192

181-
There are two main differences of `var`:
193+
There are two main differences of `var` compared to `let/const`:
182194

183-
1. Variables have no block scope, they are visible minimum at the function level.
184-
2. Variable declarations are processed at function start.
195+
1. `var` variables have no block scope, they are visible minimum at the function level.
196+
2. `var` declarations are processed at function start (script start for globals).
185197

186198
There's one more minor difference related to the global object, we'll cover that in the next chapter.
187199

188-
These differences are actually a bad thing most of the time. Block-level variables is such a great thing. That's why `let` was introduced in the standard long ago, and is now a major way (along with `const`) to declare a variable.
200+
These differences make `var` worse than `let` most of the time. Block-level variables is such a great thing. That's why `let` was introduced in the standard long ago, and is now a major way (along with `const`) to declare a variable.

1-js/09-classes/07-mixins/article.md

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,25 @@ Please note that the call to the parent method `super.say()` from `sayHiMixin` l
9999

100100
![](mixin-inheritance.png)
101101

102-
That's because methods from `sayHiMixin` have `[[HomeObject]]` set to it. So `super` actually means `sayHiMixin.__proto__`, not `User.__proto__`.
102+
That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So their `[[HomeObject]]` internal property references `sayHiMixin`, as shown on the picture above.
103+
104+
As `super` looks for parent methods in `[[HomeObject]].__proto__`, that means it searches `sayHiMixin.__proto__` for `super.say`, not `User.__proto__`.
103105

104106
## EventMixin
105107

106108
Now let's make a mixin for real life.
107109

108-
The important feature of many objects is working with events.
109-
110-
That is: an object should have a method to "generate an event" when something important happens to it, and other objects should be able to "listen" to such events.
110+
The important feature of many browser objects (not only) is working with events. Events is a way to "broadcast information" to anyone who wants it. So let's make a mixin that allows to easily add event-related functions to any class/object.
111111

112-
An event must have a name and, optionally, bundle some additional data.
112+
- The mixin will provide a method `.trigger(name, [data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, and the optional additional data may follow.
113+
- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when the event triggers.
114+
- ...And the method `.off(name, handler)` that removes `handler` listener.
113115

114-
For instance, an object `user` can generate an event `"login"` when the visitor logs in. And another object `calendar` may want to receive such events to load the calendar for the logged-in person.
116+
After adding the mixin, an object `user` will become able to generate an event `"login"` when the visitor logs in. And another object `calendar` may want to receive such events to load the calendar for the logged-in person.
115117

116-
Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may want to get that information and react on that event.
118+
Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may want to get that information and react on that event. And so on.
117119

118-
Events is a way to "share information" with anyone who wants it. They can be useful in any class, so let's make a mixin for them:
120+
Here's the code:
119121

120122
```js run
121123
let eventMixin = {
@@ -146,7 +148,7 @@ let eventMixin = {
146148
},
147149

148150
/**
149-
* Generate the event and attach the data to it
151+
* Generate an event with the given name and data
150152
* this.trigger('select', data1, data2);
151153
*/
152154
trigger(eventName, ...args) {
@@ -160,12 +162,10 @@ let eventMixin = {
160162
};
161163
```
162164

163-
There are 3 methods here:
164-
165-
1. `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name happens. The handlers are stored in the `_eventHandlers` property.
166-
2. `.off(eventName, handler)` -- removes the function from the handlers list.
167-
3. `.trigger(eventName, ...args)` -- generates the event: all assigned handlers are called and `args` are passed as arguments to them.
168165

166+
- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name happens. Technically, there's `_eventHandlers` property, that stores an array of handlers for each event name. So it just adds it to the list.
167+
- `.off(eventName, handler)` -- removes the function from the handlers list.
168+
- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`.
169169

170170
Usage:
171171

@@ -176,30 +176,31 @@ class Menu {
176176
this.trigger("select", value);
177177
}
178178
}
179-
// Add the mixin
179+
// Add the mixin with event-related methods
180180
Object.assign(Menu.prototype, eventMixin);
181181

182182
let menu = new Menu();
183183

184-
// call the handler on selection:
184+
// add a handler, to be called on selection:
185185
*!*
186186
menu.on("select", value => alert(`Value selected: ${value}`));
187187
*/!*
188188

189-
// triggers the event => shows Value selected: 123
190-
menu.choose("123"); // value selected
189+
// triggers the event => the handler above runs and shows:
190+
// Value selected: 123
191+
menu.choose("123");
191192
```
192193

193-
Now if we have the code interested to react on user selection, we can bind it with `menu.on(...)`.
194+
Now if we'd like any code to react on menu selection, we can listen to it with `menu.on(...)`.
194195

195-
And the `eventMixin` can add such behavior to as many classes as we'd like, without interfering with the inheritance chain.
196+
And `eventMixin` mixin makes it easy to add such behavior to as many classes as we'd like, without interfering with the inheritance chain.
196197

197198
## Summary
198199

199200
*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
200201

201-
Some other languages like e.g. python allow to create mixins using multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying them into the prototype.
202+
Some other languages like e.g. Python allow to create mixins using multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.
202203

203204
We can use mixins as a way to augment a class by multiple behaviors, like event-handling as we have seen above.
204205

205-
Mixins may become a point of conflict if they occasionally overwrite native class methods. So generally one should think well about the naming for a mixin, to minimize such possibility.
206+
Mixins may become a point of conflict if they occasionally overwrite native class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that.

0 commit comments

Comments
 (0)