Skip to content

Commit 480e69b

Browse files
committed
work
1 parent 776e83e commit 480e69b

File tree

87 files changed

+1020
-233
lines changed

Some content is hidden

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

87 files changed

+1020
-233
lines changed

1-js/2-first-steps/18-function-parameters/article.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,16 @@ The `...rest` must always be the last.
119119

120120
````smart header="The `arguments` variable"
121121

122-
In old times, there were no rest operator. But there was a special variable named `arguments` that contained all arguments by their index. It is still supported and can be used like this:
122+
In old times, there was no rest operator. But there is a special variable named `arguments` that contains all arguments by their index. It is still supported and can be used like this:
123123

124124
```js run
125125
function showName() {
126126
alert( arguments[0] );
127127
alert( arguments[1] );
128128
alert( arguments.length );
129+
130+
// for..of works too
131+
// for(let arg of arguments) alert(arg);
129132
}
130133
131134
// shows: Julius, Caesar, 2
@@ -135,7 +138,7 @@ showName("Julius", "Caesar");
135138
showName("Ilya");
136139
```
137140

138-
The downside is that `arguments` looks like an array, but it's not. It does not support many useful array features. It mainly exists for backwards compatibility, usually the rest operator is better.
141+
The downside is that though `arguments` looks like an array, but it's not. It does not support many useful array methods that we'll study later, and if they're needed, then the rest operator should be used.
139142
````
140143
141144
## Destructuring parameters
@@ -158,7 +161,7 @@ Like this?
158161
showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])
159162
```
160163

161-
That's ugly. And becomes unreadable if we deal with more parameters.
164+
That's ugly. And becomes unreadable when we deal with more parameters.
162165

163166
Destructuring comes to the rescue!
164167

@@ -235,13 +238,13 @@ showMenu(); // Menu 100 200
235238

236239
In the code above, the whole arguments object is `{}` by default, so there's always something to destructurize.
237240

238-
## The spread operator
241+
## The spread operator [#spread-operator]
239242

240243
As we've seen before, the rest operator `...` allows to gather parameters in the array.
241244

242245
But there's a reverse named "the spread operator". It also looks like `...` and works at call-time.
243246

244-
The spread operator allows to "unfurl" an array into a list of parameters, like this:
247+
The spread operator allows to convert an array into a list of parameters, like this:
245248

246249
```js run
247250
let fullName = ["Gaius", "Julius", "Caesar"];
@@ -256,7 +259,6 @@ function showName(firstName, secondName, lastName) {
256259
showName(...fullName);
257260
```
258261

259-
260262
Let's see a more real-life example.
261263

262264
There exist a built-in function [Math.max](mdn:js/Math/max) that takes a list of values and returns the greatest one:
@@ -276,13 +278,14 @@ alert( Math.max(...arr) ); // 7
276278

277279
In short:
278280
- When `...` occurs in function parameters, it's called a "rest operator" and gathers parameters into the array.
279-
- When `...` occurs in a function call, it's called a "spread operator" and unfurls an array into the list.
281+
- When `...` occurs in a function call, it's called a "spread operator" and converts an array into the list.
280282

281283
Together they help to travel between a list and an array of parameters with ease.
282284

283285

284286
## Summary TODO
285287

288+
[todo]
286289
Основные улучшения в функциях:
287290

288291
- Можно задавать параметры по умолчанию, а также использовать деструктуризацию для чтения приходящего объекта.

1-js/2-first-steps/19-function-create-advanced/article.md renamed to 1-js/2-first-steps/19-function-expressions-arrows/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Function expressions and more
1+
# Function expressions and arrows
22

33
In JavaScript, a function is a value.
44

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
**Error**!
2+
3+
Try it:
4+
5+
```js run
6+
let user = {
7+
name: "John",
8+
go: function() { alert(this.name) }
9+
}
10+
11+
(user.go)() // error!
12+
```
13+
14+
The error message in most browsers does not give understanding what went wrong.
15+
16+
**The error appears because a semicolon is missing after `user = {...}`.**
17+
18+
Javascript does not assume a semicolon before a bracket `(user.go)()`, so it reads the code like:
19+
20+
```js no-beautify
21+
let user = { go:... }(user.go)()
22+
```
23+
24+
Then we can also see that such a joint expression is syntactically a call of the object `{ go: ... }` as a function with the argument `(user.go)`. And that also happens on the same line with `let user`, so the `user` object has not yet even been defined, hence the error.
25+
26+
If we insert the semicolon, all is fine:
27+
28+
```js run
29+
let user = {
30+
name: "John",
31+
go: function() { alert(this.name) }
32+
}*!*;*/!*
33+
34+
(user.go)() // John
35+
```
36+
37+
Please note that brackets around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters.
38+
39+
40+
41+
42+
43+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
importance: 2
2+
3+
---
4+
5+
# Syntax check
6+
7+
What is the resule of this code?
8+
9+
10+
```js no-beautify
11+
let user = {
12+
name: "John",
13+
go: function() { alert(this.name) }
14+
}
15+
16+
(user.go)()
17+
```
18+
19+
P.S. There's a pitfall :)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Here's the explanations.
3+
4+
1. That's a regular object method call.
5+
6+
2. The same, brackets do not change the order of operations here, the dot is first anyway.
7+
8+
3. Here we have a more complex call `(expression).method()`. The call works as if it were split into two lines:
9+
10+
```js no-beautify
11+
f = obj.go; // calculate the expression
12+
f(); // call what we have
13+
```
14+
15+
Here `f()` is executed as a function, without `this`.
16+
17+
4. The similar thing as `(3)`, to the left of the dot `.` we have an expression.
18+
19+
To explain the behavior of `(3)` and `(4)` we need to recall that property accessors (dot or square brackets) return a value of the Reference Type.
20+
21+
Any operation on it except a method call (like assignment `=` or `||`) turns it into an ordinary value, which does not carry the information allowing to set `this`.
22+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
importance: 3
2+
3+
---
4+
5+
# Explain the value of "this"
6+
7+
In the code above we intend to call `user.go()` method 4 times in a row.
8+
9+
But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why?
10+
11+
```js run no-beautify
12+
let obj, method;
13+
14+
obj = {
15+
go: function() { alert(this); }
16+
};
17+
18+
obj.go(); // (1) [object Object]
19+
20+
(obj.go)(); // (2) [object Object]
21+
22+
(method = obj.go)(); // (3) undefined
23+
24+
(obj.go || obj.stop)(); // (4) undefined
25+
```
26+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
**Answer: an error.**
2+
3+
Try it:
4+
```js run
5+
function makeUser() {
6+
return {
7+
name: "John",
8+
ref: this
9+
};
10+
};
11+
12+
let user = makeUser();
13+
14+
alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
15+
```
16+
17+
That's because rules that set `this` do not look at object literals.
18+
19+
Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method.
20+
21+
And the object literal itself has no effect on `this`. The value of `this` is one for the whole function, code blocks and object literals do not affect it.
22+
23+
So `ref: this` actually takes current `this` of the function.
24+
25+
Here's the opposite case:
26+
27+
```js run
28+
function makeUser() {
29+
return {
30+
name: "John",
31+
*!*
32+
ref() {
33+
return this;
34+
}
35+
*/!*
36+
};
37+
};
38+
39+
let user = makeUser();
40+
41+
alert( user.ref().name ); // John
42+
```
43+
44+
Now it works, because `user.ref()` is a method. And the value of `this` is set to the object before dot `.`.
45+
46+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
importance: 5
2+
3+
---
4+
5+
# Using "this" in object literal
6+
7+
Here the function `makeUser` returns an object.
8+
9+
What is the result of accessing its `ref`? Why?
10+
11+
```js
12+
function makeUser() {
13+
return {
14+
name: "John",
15+
ref: this
16+
};
17+
};
18+
19+
let user = makeUser();
20+
21+
alert( user.ref.name ); // What's the result?
22+
```
23+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
let calculator = {
2+
sum() {
3+
return this.a + this.b;
4+
},
5+
6+
mul() {
7+
return this.a * this.b;
8+
},
9+
10+
read() {
11+
this.a = +prompt('a?', 0);
12+
this.b = +prompt('b?', 0);
13+
}
14+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
3+
describe("calculator", function() {
4+
5+
context("when 2 and 3 entered", function() {
6+
beforeEach(function() {
7+
sinon.stub(window, "prompt");
8+
9+
prompt.onCall(0).returns("2");
10+
prompt.onCall(1).returns("3");
11+
12+
calculator.read();
13+
});
14+
15+
afterEach(function() {
16+
prompt.restore();
17+
});
18+
19+
it("the sum is 5", function() {
20+
assert.equal(calculator.sum(), 5);
21+
});
22+
23+
it("the multiplication product is 6", function() {
24+
assert.equal(calculator.mul(), 6);
25+
});
26+
});
27+
28+
});

0 commit comments

Comments
 (0)