-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
49 changed files
with
689 additions
and
271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 1 addition & 33 deletions
34
1-js/8-more-functions/08-call-apply-decorators/2-spy-decorator/solution.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1 @@ | ||
Решение аналогично задаче <info:task/logging-decorator>, разница в том, что в лог вместо одного аргумента идет весь объект `arguments`. | ||
|
||
Для передачи вызова с произвольным количеством аргументов используем `f.apply(this, arguments)`. | ||
|
||
```js run | ||
function work(a, b) { | ||
alert( a + b ); // work - произвольная функция | ||
} | ||
|
||
function makeLogging(f, log) { | ||
|
||
*!* | ||
function wrapper() { | ||
log.push([].slice.call(arguments)); | ||
return f.apply(this, arguments); | ||
} | ||
*/!* | ||
|
||
return wrapper; | ||
} | ||
|
||
var log = []; | ||
work = makeLogging(work, log); | ||
|
||
work(1, 2); // 3 | ||
work(4, 5); // 9 | ||
|
||
for (var i = 0; i < log.length; i++) { | ||
var args = log[i]; // массив из аргументов i-го вызова | ||
alert( 'Лог:' + args.join() ); // "Лог:1,2", "Лог:4,5" | ||
} | ||
``` | ||
|
||
Here we can use `log.push(args)` to store all arguments in the log and `f.apply(this, args)` to forward the call. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# Arrow functions revisited | ||
|
||
Let's revisit arrow functions. | ||
|
||
[cut] | ||
|
||
Arrow functions are not just a "shorthand" for writing small stuff. | ||
|
||
Javascript is full of situations where we need to write a small function, that's executed somewhere else. | ||
|
||
For instance: | ||
|
||
- `arr.forEach(func)` -- `func` is executed by `forEach` for every array item. | ||
- `setTimeout(func)` -- `func` is executed by the built-in scheduler. | ||
- ...there are more. | ||
|
||
It's very in the spirit of Javascript to create a function and pass it somewhere. | ||
|
||
And in such functions we usually don't want to leave the current context. | ||
|
||
## Arrow functions have no "this" | ||
|
||
As we remember from the chapter <info:object-methods>, arrow functions do not have `this`. If `this` is accessed, it is taken from the outside. | ||
|
||
For instance, we can use it to iterate inside an object method: | ||
|
||
```js run | ||
let group = { | ||
title: "Our Group", | ||
students: ["John", "Pete", "Alice"], | ||
|
||
showList() { | ||
*!* | ||
this.students.forEach( | ||
student => alert(this.title + ': ' + student) | ||
); | ||
*/!* | ||
} | ||
}; | ||
|
||
group.showList(); | ||
``` | ||
|
||
Here in `forEach`, the arrow function is used, so `this.title` in it is exactly the same as in the outer method `showList`. That is: `group.title`. | ||
|
||
If we used a "regular" function, there would be an error: | ||
|
||
```js run | ||
let group = { | ||
title: "Our Group", | ||
students: ["John", "Pete", "Alice"], | ||
|
||
showList() { | ||
*!* | ||
this.students.forEach(function(student) { | ||
// Error: Cannot read property 'title' of undefined | ||
alert(this.title + ': ' + student) | ||
}); | ||
*/!* | ||
} | ||
}; | ||
|
||
group.showList(); | ||
``` | ||
|
||
The error occurs because `forEach` runs functions with `this=undefined` by default, so the attempt to access `undefined.title` is made. | ||
|
||
That doesn't affect arrow functions, because they just don't have `this`. | ||
|
||
```warn header="Arrow functions can't run with `new`" | ||
Not having `this` naturally means another limitation: arrow functions can't be used as constructors. They can't be called with `new`. | ||
``` | ||
```smart header="Arrow functions VS bind" | ||
There's a subtle difference between an arrow function `=>` and a regular function called with `.bind(this)`: | ||
- `.bind(this)` creates a "bound version" of the function. | ||
- The arrow `=>` doesn't create any binding. The function simply doesn't have `this`. The lookup of `this` is made exactly the same way as a regular variable search: in the outer lexical environment. | ||
``` | ||
|
||
## Arrows have no "arguments" | ||
|
||
Arrow functions also have no `arguments` variable. | ||
|
||
That's great for decorators, when we need to forward a call with the current `this` and `arguments`. | ||
|
||
For instance, `defer(f, ms)` gets a function and returns a wrapper around it that delays the call by `ms` milliseconds: | ||
|
||
```js run | ||
function defer(f, ms) { | ||
return function() { | ||
setTimeout(() => f.apply(this, arguments), ms) | ||
}; | ||
} | ||
|
||
function sayHi(who) { | ||
alert('Hello, ' + who); | ||
} | ||
|
||
let sayHiDeferred = defer(sayHi, 2000); | ||
sayHiDeferred("John"); // Hello, John after 2 seconds | ||
``` | ||
|
||
The same without an arrow function would look like: | ||
|
||
Аналогичная реализация без функции-стрелки выглядела бы так: | ||
|
||
```js | ||
function defer(f, ms) { | ||
return function(...args) { | ||
let ctx = this; | ||
setTimeout(function() { | ||
return f.apply(ctx, args); | ||
}, ms); | ||
}; | ||
} | ||
``` | ||
|
||
Here we had to create additional variables `args` and `ctx` so that the function inside `setTimeout` could take them. | ||
|
||
## Summary | ||
|
||
Arrow functions: | ||
|
||
- Do not have `this`. | ||
- Do not have `arguments`. | ||
- Can't be called with `new`. | ||
- (They also don't have `super`, but we didn't study it. Will be in the chapter <info:class-inheritance>). | ||
|
||
That's because they are meant for short pieces of code that does not have the own "context", but rather works in the current one. And they really shine in that use case. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
-3.15 KB
(84%)
1-js/9-object-inheritance/04-function-prototype/object-prototype-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-8.42 KB
(83%)
1-js/9-object-inheritance/04-function-prototype/object-prototype-1@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-3.06 KB
(78%)
1-js/9-object-inheritance/04-function-prototype/object-prototype.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-8.3 KB
(76%)
1-js/9-object-inheritance/04-function-prototype/object-prototype@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.