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/06-advanced-functions/04-var/article.md
+18-6Lines changed: 18 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -45,7 +45,19 @@ alert(test); // true, the variable lives after if
45
45
*/!*
46
46
```
47
47
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
+
```
49
61
50
62
The same thing for loops: `var` cannot be block- or loop-local:
51
63
@@ -76,7 +88,7 @@ alert(phrase); // Error: phrase is not defined (Check the Developer Console)
76
88
77
89
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.
78
90
79
-
## "var" are processed at the function start
91
+
## "var" declarations are processed at the function start
80
92
81
93
`var` declarations are processed when the function starts (or script starts for globals).
82
94
@@ -178,11 +190,11 @@ In both examples above `alert` runs without an error, because the variable `phra
178
190
179
191
## Summary
180
192
181
-
There are two main differences of `var`:
193
+
There are two main differences of `var` compared to `let/const`:
182
194
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).
185
197
186
198
There's one more minor difference related to the global object, we'll cover that in the next chapter.
187
199
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.
Copy file name to clipboardExpand all lines: 1-js/09-classes/07-mixins/article.md
+23-22Lines changed: 23 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -99,23 +99,25 @@ Please note that the call to the parent method `super.say()` from `sayHiMixin` l
99
99
100
100

101
101
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__`.
103
105
104
106
## EventMixin
105
107
106
108
Now let's make a mixin for real life.
107
109
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.
111
111
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.
113
115
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.
115
117
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.
117
119
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:
119
121
120
122
```js run
121
123
let eventMixin = {
@@ -146,7 +148,7 @@ let eventMixin = {
146
148
},
147
149
148
150
/**
149
-
* Generate the event and attach the data to it
151
+
* Generate an event with the given name and data
150
152
* this.trigger('select', data1, data2);
151
153
*/
152
154
trigger(eventName, ...args) {
@@ -160,12 +162,10 @@ let eventMixin = {
160
162
};
161
163
```
162
164
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.
168
165
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`.
// 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");
191
192
```
192
193
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(...)`.
194
195
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.
196
197
197
198
## Summary
198
199
199
200
*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
200
201
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.
202
203
203
204
We can use mixins as a way to augment a class by multiple behaviors, like event-handling as we have seen above.
204
205
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