Skip to content

Commit 83b93e5

Browse files
committed
up
1 parent 63f55dc commit 83b93e5

File tree

49 files changed

+689
-271
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+689
-271
lines changed

1-js/4-object-basics/04-object-methods/article.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,11 @@ Please note that usually a call of a function using `this` without an object is
219219
```smart header="The consequences of unbound `this`"
220220
If you come from another programming languages, then you are probably used to an idea of a "bound `this`", where methods defined in an object always have `this` referencing that object.
221221

222-
The idea of unbound, run-time evaluated `this` has both pluses and minuses. From one side, a function can be reused for different objects. From the other side, greater flexibility opens a place for mistakes.
222+
The idea of unbound, run-time evaluated `this` has both pluses and minuses. From one side, a function can be reused for different objects. From the other side, greater flexibility opens a place for mistakes.
223223

224224
Here we are not to judge whether this language design decision is good or bad. We will understand how to work with it, how to get benefits and evade problems.
225225
```
226+
226227
## Internals: Reference Type
227228
228229
An intricate method call can loose `this`, for instance:
@@ -295,6 +296,27 @@ Any other operation like assignment `hi = user.hi` discards the reference type a
295296

296297
So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj[method]()` syntax (they do the same here).
297298

299+
````warn header="Arrow functions do not have `this`"
300+
Arrow functions are special: they don't have "own" `this`. If we reference `this` from such function, it's taken from the outer "normal" function.
301+
302+
For instance, here `arrow()` uses `this` from the outer `user.sayHi()` method:
303+
304+
```js run
305+
let user = {
306+
firstName: "Ilya",
307+
sayHi() {
308+
let arrow = () => alert(this.firstName);
309+
arrow();
310+
}
311+
};
312+
313+
user.sayHi(); // Ilya
314+
```
315+
316+
That's a special feature of arrow functions, it's useful when we actually do not want to have a separate `this`, but rather to take it from the outer context. Later in the chapter <info:arrow-functions> we'll dig more deeply into what's going on.
317+
318+
````
319+
298320
## Summary
299321
300322
[todo]

1-js/5-data-types/01-primitives-methods/article.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,39 @@ alert( n.toFixed(2) ); // 1.23
8181

8282
We'll see more specific methods in chapters <info:number> and <info:string>.
8383

84+
85+
````warn header="Constructors `String/Number/Boolean` are for internal use only"
86+
Some languages like Java allow to create "wrapper objects" for primitives explicitly using syntax like `new Number(1)` or `new Boolean(false)`.
87+
88+
In Javascript that's also possible for historical reasons, but highly not recommended. Things will go crazy in many places.
89+
90+
For instance:
91+
92+
```js run
93+
alert( typeof 1 ); // "number"
94+
95+
alert( typeof new Number(1) ); // "object"!
96+
```
97+
98+
And, because `zero` is an object:
99+
100+
```js run
101+
let zero = new Number(0);
102+
103+
if (zero) { // zero is true, because it's an object
104+
alert( "zero is truthy?!?" );
105+
}
106+
```
107+
108+
From the other side, using same functions `String/Number/Boolean` without `new` is a totally sane and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive).
109+
110+
This is totally valid:
111+
```js
112+
let num = Number("123"); // convert a string to number
113+
```
114+
````
115+
116+
84117
````warn header="null/undefined have no methods"
85118
Special primitives `null` and `undefined` are exceptions. They have no corresponding "wrapper objects" and provide no methods. In a sense, they are "the most primitive".
86119

1-js/5-data-types/05-array-methods/article.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -606,32 +606,31 @@ alert(typeof {}); // object
606606
alert(typeof []); // same
607607
```
608608

609-
There's a special method for that [Array.isArray(value)](mdn:js/Array/isArray) that returns `true` if the `value` is an array, and `false` otherwise.
609+
...But arrays are used so often that there's a special method for that: [Array.isArray(value)](mdn:js/Array/isArray). It returns `true` if the `value` is an array, and `false` otherwise.
610610

611611
```js run
612612
alert(Array.isArray({})); // false
613613

614614
alert(Array.isArray([])); // true
615615
```
616616

617-
```smart header="`Array.isArray` vs other type-checks"
618-
You remembeare other ways to check for
619-
620617
## Methods: "thisArg"
621618

622619
Almost all array methods that call functions -- like `find`, `filter`, `map`, with a notable exception of `sort`, accept an optional additional parameter `thisArg`.
623620

624-
The full syntax is:
621+
In the sections above that parameter is not explained, because it's rarely used.
622+
623+
But for completeness here's the full syntax:
625624

626625
```js
627-
let result = arr.find(func, thisArg);
628-
let results = arr.filter(func, thisArg);
629-
// etc, thisArg goes after the function
626+
arr.find(func, thisArg);
627+
arr.filter(func, thisArg);
628+
arr.map(func, thisArg);
629+
// ...
630+
// thisArg is the optional last argument
630631
```
631632

632-
It is used sparingly, but we have to cover it here for the sake of completeness.
633-
634-
The value of `thisArg` parameter becomes `this` for the function.
633+
The value of `thisArg` parameter becomes `this` for `func`.
635634

636635
For instance, here we use an object method as a filter:
637636

@@ -657,7 +656,7 @@ let youngerUsers = users.filter(user.younger, user);
657656
alert(youngerUsers.length); // 2
658657
```
659658

660-
In the call above, we use `user.younger` as a filter and also provide `user` as the context for it. If we did't provide the context, `users.filter(user.younger)` would call `user.younger` as a standalone function, with `this=undefined`. That would be an instant error.
659+
In the call above, we use `user.younger` as a filter and also provide `user` as the context for it. If we did't provide the context, `users.filter(user.younger)` would call `user.younger` as a standalone function, with `this=undefined`. That would mean an instant error.
661660

662661
## Other methods
663662

@@ -676,7 +675,7 @@ These and other methods are also listed in the [manual](mdn:js/Array).
676675

677676
## Summary
678677

679-
Most often methods:
678+
Most used array methods:
680679

681680
- `split/join` -- convert a string to array and back.
682681
- `splice` -- delete and insert elements at the given position.
File renamed without changes.
File renamed without changes.
File renamed without changes.

1-js/8-more-functions/02-rest-parameters-spread-operator/article.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ Also, it always has all arguments in it, we can't capture them partially, like w
107107

108108
So when we need these features, then rest parameters are preferred.
109109

110+
````smart header="Arrow functions do not have `\"arguments\"`"
111+
If we access the `arguments` object from an arrow function, it takes them from the outer "normal" function.
112+
113+
Here's an example:
114+
115+
```js run
116+
function f() {
117+
let showArg = () => alert(arguments[0]);
118+
showArg();
119+
}
120+
121+
f(1); // 1
122+
```
123+
As we remember, arrow functions don't have own `this`. Now we know they don't have the special `arguments` object too.
124+
125+
````
126+
110127
## Spread operator [#spread-operator]
111128
112129
We've just seen how to get an array from the list of parameters.

1-js/8-more-functions/03-closure/2-counter-object-independent/solution.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

2-
Both nested functions are created within the same Lexical Environment.
2+
Surely it will work just fine.
33

4-
So they share the same `count`:
4+
Both nested functions are created within the same outer Lexical Environment, so they share access to the same `count` variable:
55

66
```js run
77
function Counter() {
@@ -10,6 +10,7 @@ function Counter() {
1010
this.up = function() {
1111
return ++count;
1212
};
13+
1314
this.down = function() {
1415
return --count;
1516
};
Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1 @@
1-
Решение аналогично задаче <info:task/logging-decorator>, разница в том, что в лог вместо одного аргумента идет весь объект `arguments`.
2-
3-
Для передачи вызова с произвольным количеством аргументов используем `f.apply(this, arguments)`.
4-
5-
```js run
6-
function work(a, b) {
7-
alert( a + b ); // work - произвольная функция
8-
}
9-
10-
function makeLogging(f, log) {
11-
12-
*!*
13-
function wrapper() {
14-
log.push([].slice.call(arguments));
15-
return f.apply(this, arguments);
16-
}
17-
*/!*
18-
19-
return wrapper;
20-
}
21-
22-
var log = [];
23-
work = makeLogging(work, log);
24-
25-
work(1, 2); // 3
26-
work(4, 5); // 9
27-
28-
for (var i = 0; i < log.length; i++) {
29-
var args = log[i]; // массив из аргументов i-го вызова
30-
alert( 'Лог:' + args.join() ); // "Лог:1,2", "Лог:4,5"
31-
}
32-
```
33-
1+
Here we can use `log.push(args)` to store all arguments in the log and `f.apply(this, args)` to forward the call.

1-js/8-more-functions/08-call-apply-decorators/article.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ Taken from the specification almost "as-is":
434434

435435
So, technically it takes `this` and joins `this[0]`, `this[1]` ...etc together. It's intentionally written in a way that allows any array-like `this` (not a coincidence, many methods follow this practice). That's why it also works with `this=arguments`.
436436

437-
438437
## Summary
439438

440439
*Decorator* is a wrapper around a function that alters its behavior. The main job is still carried out by the function.

0 commit comments

Comments
 (0)