Skip to content

Commit f1b7de0

Browse files
committed
ok
1 parent 98c987e commit f1b7de0

File tree

5 files changed

+100
-113
lines changed

5 files changed

+100
-113
lines changed

1-js/2-first-steps/19-function-expression/article.md

Lines changed: 79 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,11 @@ alert( sayHi ); // shows the function code
4242

4343
Note that there are no brackets after `sayHi` in the last line.
4444

45-
The function is not called there. There are programming languages where any use of function name causes it's call, but JavaScript is not like that. In JavaScript, a function is a value and we can deal with that as a value, like print string representation, that is the source code.
45+
The function is not called there. There are programming languages where any use of function name causes it's call, but JavaScript is not like that. In JavaScript, a function is a value and we can deal with that as a value. The code above shows its string representation, that is its source code.
4646

47+
It is a special value of course, in the sense that we can call it using brackets: `"sayHi()"`.
4748

48-
It is a special value though, in the sense that we can call it using brackets: `"sayHi()"`, but only if we explicitly put brackets into the code.
49-
50-
Other actions with functions are also available, in the same fashion as with other values.
49+
But it's still a value. So we can work with it like with other kinds of values.
5150

5251
We can copy a function to another variable:
5352

@@ -59,23 +58,18 @@ function sayHi() { // (1) create
5958
let func = sayHi; // (2) copy
6059

6160
func(); // Hello // (3) call the copy (it works)!
62-
63-
sayHi = null; // (4) store null in the old variable
64-
sayHi(); // error! (now null, the function is overwritten)
65-
66-
func(); // the copy still works
61+
sayHi(); // Hello // this works too (why wouldn't it)
6762
```
6863

6964
In more detail:
7065
1. Function Declaration `(1)` creates the function and puts it into the variable `sayHi`"
7166
2. Line `(2)` copies it into variable `func`.
7267

73-
Please note again: there are no brackets after `sayHi`. If they were, then `func = sayHi()` would write *the result* of the call `sayHi()` into `func`, not the function `sayHi` itself.
74-
3. At the moment `(3)` the function can be called both as `sayHi()` and `func()`.
75-
4. ...We can overwrite `sayHi`, it have had the function, but now it stores `null`. Naturally, the call attempt would fail.
76-
5. But `func` still has the function, it is still callable.
68+
Please note again: there are no brackets after `sayHi`. If they were, then `func = sayHi()` would write *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself.
69+
3. Now the function can be called both as `sayHi()` and `func()`.
7770

78-
Note, that we could use a Function Expression in the first line: `let sayHi = function() { ... }`. Everything would work the same.
71+
72+
Note, that we could also have used a Function Expression to declare `sayHi`, in the first line: `let sayHi = function() { ... }`. Everything would work the same.
7973

8074
```smart header="A function is a value representing an \"action\""
8175
Regular values like strings or numbers represent the *data*.
@@ -85,54 +79,78 @@ A function can be perceived as an *action*.
8579
We can copy it between variables and run when we want.
8680
```
8781

88-
## Why Function Expression?
82+
## Function Expression as a method
83+
84+
Now let's go back: we have two ways of declaring a function. Do we really need both? What's about Function Expressions that makes it a good addition?
8985

90-
Now let's go back: we have two ways of declaring a function. Why so? What's about Function Expressions that makes it a good addition?
86+
Actually, yes. We'll see many examples below, but let's start with objects.
9187

92-
**Function Expressions are very convenient for creating an action in-place and passing it along the code.**
88+
As we remember from the chapter <info:types>, objects are data structures meant to store collections of data.
89+
90+
Most often, we create objects to represent entities of the real world, like here:
91+
92+
```js
93+
let user = {
94+
name: "John",
95+
age: 30
96+
};
97+
```
9398

94-
There is a built-in [setTimeout](https://developer.mozilla.org/en/docs/Web/API/WindowTimers/setTimeout) function in JavaScript, that can schedule a function to run after a given period of time.
99+
In the real world, a user can `act`, like: select something from the shopping cart, login, logout etc. For the start, let's teach him to say hello:
95100

96-
The syntax is: `setTimeout(func, ms, ...arguments)`:
101+
```js run
102+
let user = {
103+
name: "John",
104+
age: 30
105+
};
97106

98-
`func`
99-
: The function to run.
107+
*!*
108+
user.sayHi = function() {
109+
alert("Hello!");
110+
};
111+
*/!*
100112

101-
`ms`
102-
: The number of milliseconds (1/1000 of a second) to schedule the call after.
113+
user.sayHi(); // Hello!
114+
```
103115

104-
`arguments`
105-
: One of more arguments to pass to the function.
116+
You see? We've just used a Function Expression to create the function and assign it to the property `user.sayHi` of the object.
106117

107-
What if we wanted to say "Hello" in a second?
118+
Then we can call it any time. The user now can speak!
108119

109-
One could write a code like this:
120+
That is how a so-called "object-oriented code" is written. We make objects which reflect entities of the real world: like a user, or a document, or a button that is clickable etc.
110121

111-
```js run
112-
function sayHi() {
113-
alert("Hello!")
114-
}
122+
An object stores its data in regular properties (like `name`, `age` etc) and has functions to express itself. Function properties are usually called *methods*. So, one can say that in the code above "`sayHi` is a method of the object `user`".
115123

116-
setTimeout(sayHi, 1000);
117-
```
118124

119-
That would work. But we have declared a function that has no future use.
120125

121-
A Function Expression is much cleaner:
126+
Of course we could use a Function Declaration for the same purpose:
122127

123128
```js run
124-
setTimeout(function() {
125-
alert("Hello!")
126-
}, 1000);
129+
let user = {
130+
// ...
131+
};
132+
133+
*!*
134+
function sayHi() {
135+
alert("Hello!");
136+
};
137+
138+
user.sayHi = sayHi;
139+
*/!*
140+
141+
user.sayHi(); // Hello!
127142
```
128143

129-
Such functions are sometimes called "anonymous" meaning that they are defined without a name. So to say, we can't reuse them, because there is no variable for them. But here it's exactly what we want.
144+
That would also work, but is longer. Also we get an "extra" function `sayHi` outside of the `user` object. Here we don't want it.
130145

131-
Creating functions in-place is very natural and in the spirit of JavaScript.
132146

133147
## Function Expression vs Function Declaration
134148

135-
Let's briefly reformulate the distinction between these two.
149+
Let's formulate key differences between Function Declarations and Expressions.
150+
151+
### What's where
152+
153+
Here's the exact distinction between these two.
136154

137155
- *Function Declaration:* a function, declared as a separate statement, in the main code flow.
138156

@@ -144,37 +162,27 @@ Let's briefly reformulate the distinction between these two.
144162
```
145163
- *Function Expression:* a function, created in the context of an expression.
146164

147-
Here the function is created in the context of an "assignment expression", it's an expression:
165+
Here the function is created in the context of an "assignment expression":
148166
```js
149167
// Function Expression
150168
let sum = function(a, b) {
151169
return a + b;
152170
}
153171
```
154172

155-
Here the function is created inside another function call:
156-
157-
```js
158-
// Function Expression
159-
setTimeout(function() {
160-
alert("Hello!")
161-
}, 1000);
162-
```
163-
164173
### Creation time
165174

166-
There are more differences between them besides the syntax.
175+
Another difference is when they are actualy created by the JavaScript engine.
167176

168177
**Function Expressions are created when the execution reaches them.**
169178

170-
That's rather obvious. Once the execution flow passes to the right side of the assignment -- here we go, the function is made and can be used (assigned, called etc) from now on.
179+
That's kind of obvious. Once the execution flow passes to the right side of the assignment `let sum = function` -- here we go, the function is made and can be used (assigned, called etc) from now on.
171180
172181
Function Declarations are different.
173182
174-
**Function Declarations are created before the script or a code block begins to execute and are visible in the whole scropt/block.**
175-
176-
In other words, when JavaScript *prepares* to run the script or a code block, it first looks for Function Declarations in it and creates the functions. We can think of it as an "initialization stage". Then it runs the code.
183+
**Function Declarations are created before the script or a code block begins to execute and are visible in the whole script/block.**
177184
185+
In other words, when JavaScript *prepares* to run the script or a code block, it first looks for Function Declarations in it and creates the functions. We can think of it as an "initialization stage".
178186
179187
As a natural effect, a function declared as Function Declaration can be called earlier than it is defined.
180188
@@ -190,7 +198,7 @@ function sayHi(name) {
190198
}
191199
```
192200
193-
Function Declaration `sayHi` is created when the script starts and is visible everywhere in it.
201+
Function Declaration `sayHi` is created when JavaScript is preparing to start the script and is visible everywhere in it.
194202
195203
...And if there were Function Expression, then it wouldn't work:
196204

@@ -204,7 +212,7 @@ let sayHi = function(name) { // (*)
204212
};
205213
```
206214

207-
Function Expressions are created when the execution reaches them. No magic. That would happen only in the line `(*)`. Too late.
215+
Now there's no magic. Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late.
208216
209217
210218
### Visibility
@@ -253,24 +261,27 @@ if (age < 18) {
253261
welcome(); // \ (runs)
254262
*/!*
255263
// |
256-
function welcome() { // |
257-
alert("Hello!"); // | welcome is available everywhere in its block
258-
} // |
264+
function welcome() { // |
265+
alert("Hello!"); // | Function Declaration is available
266+
} // | everywhere in the block when it's declared
259267
// |
260268
*!*
261269
welcome(); // / (runs)
262270
*/!*
263271
264272
} else {
265273
// \
266-
function welcome() { // |
267-
alert("Greetings!"); // | another welcome is limited to its own block
268-
} // |
274+
function welcome() { // |
275+
alert("Greetings!"); // | as we don't enter this block,
276+
} // | this "welcome" is never created
269277
// /
270278
}
271279
280+
// Now we're out of figure brackets,
281+
// so we can not see Function Declarations made inside of them.
282+
272283
*!*
273-
welcome(); // Error: outside of the block there's no welcome
284+
welcome(); // Error: welcome is not defined
274285
*/!*
275286
```
276287

@@ -306,22 +317,17 @@ Or we could go on to simplify it even further using a question mark operator `?`
306317
let age = prompt("What is your age?", 18);
307318
308319
let welcome = (age < 18) ?
309-
function() {
310-
alert("Hello!");
311-
} :
312-
function() {
313-
alert("Greetings!");
314-
}
320+
function() { alert("Hello!"); } : function() { alert("Greetings!"); }
315321
316322
*!*
317323
welcome(); // ok now
318324
*/!*
319325
```
320326

321327
```smart header="What to choose: a Declaration or an Expression?"
322-
As a rule of thumb, a Function Declaration is prefered. It gives more freedom in how to organize our code, because we can call it both above and below. It's also a little bit easier to look up Function Declarations in the text.
328+
As a rule of thumb, a Function Declaration is prefered. It gives more freedom in how to organize our code, because we can call it both above and below. It's also a little bit easier to look up Function Declarations in the code, they increase readability of the code.
323329
324-
But if a Function Declaration does not suit us for some reason, or we need to create an anonymous function "at-place", then a Function Expression should be used.
330+
But if a Function Declaration does not suit us for some reason, then a Function Expression should be used.
325331
```
326332

327333
## Summary

1-js/4-data-structures/1-primitives-as-objects/1-string-new-property/solution.md renamed to 1-js/2-first-steps/20-primitives-as-objects/1-string-new-property/solution.md

File renamed without changes.

1-js/4-data-structures/1-primitives-as-objects/1-string-new-property/task.md renamed to 1-js/2-first-steps/20-primitives-as-objects/1-string-new-property/task.md

File renamed without changes.

1-js/4-data-structures/1-primitives-as-objects/article.md renamed to 1-js/2-first-steps/20-primitives-as-objects/article.md

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
# Types: Primitives as Objects
1+
# Primitives as objects
22

33
As we know from the chapter <info:types>, there are 7 data types in JavaScript:
44

55
- Six primitive types: `string`, `number`, `boolean`, `symbol`, `null` and `undefined`.
66
- One `object` type for anything else.
77

8-
In this section of the tutorial we are going to study them in more detail. But first let's learn more about how primitives and objects are related.
9-
10-
## Primitives as objects
11-
12-
Before this chapter, we discussed primitives and objects as something truly separate. But in some aspects, JavaScript allows to work with primitives as if they were objects. This ability may even lead to opinions like 'everything in JavaScript behaves as an object'. But in fact it's not quite so. And here we plan to put it clear.
8+
In this section we'll see how JavaScript allows to work with primitives as if they were objects. This ability may even lead to opinions like 'everything in JavaScript behaves as an object'. Of course in fact it's not so. And here we plan to make it clear.
139

1410
Let's formulate the definitive distinction between primitives and objects.
1511

@@ -18,46 +14,32 @@ A primitive
1814

1915
An object
2016
: Is capable of storing multiple values as properties.
21-
An empty object: `{}`. An object with two properties: `{name: "John", age: 30}`.
22-
23-
Objects in JavaScript are not just a "collection of values". One of best things about them is that we can store a function as one of properties:
17+
An empty object: `{}`. An object with two properties: `{name: "John", age: 30}`. There are other kinds of objects in JavaScript too, we'll study them later.
2418

19+
One of the best thing about objects is that they are not just a "collection of values". We can store a function as one of properties:
2520

2621
```js run
27-
let john = { name: "John" };
28-
29-
john.sayHi = function() {
30-
alert("Hi buddy!");
31-
}
32-
33-
john.sayHi(); // (*)
34-
```
35-
36-
Now as we assigned a function to `john.sayHi`, the object can speak!
37-
38-
That is how a so-called "object-oriented code" is written. We make objects which reflect entities of the real world: like a user John, or a document, or a button that is clickable etc.
39-
40-
An object stores its data in regular properties (like `name`, `age` etc) and has functions to express itself. Function properties are usually called *methods*. So, one can say that in the code above "`sayHi` is a method of the object `john`".
41-
42-
43-
44-
```warn header="Brackets are required for the call"
45-
Please note that we do need brackets in line `(*)` after `john.sayHi` if we want to run the method.
46-
47-
Without them, `john.sayHi` only gives us the function, doesn't run it.
22+
let john = {
23+
name: "John",
24+
sayHi: function() {
25+
alert("Hi buddy!");
26+
}
27+
};
28+
29+
john.sayHi(); // Hi buddy!
4830
```
4931

32+
That's very convenient in practice.
5033

51-
52-
There are many kinds of objects, including those that work with dates, errors, parts of the webpage etc. They have different properties and methods.
34+
There are many kinds of objects, including those that work with dates, errors, HTML elements etc. They have different properties and methods.
5335

5436
But features come at a price. Objects are "heavier" than primitives. They require additional resources for the machinery. But accessing properties and methods looks good. We can easily create methods of our own.
5537

56-
## Primitive as an object
38+
## A primitive as an object
5739

5840
So here's the paradox faced by the creator of JavaScript:
5941

60-
- Objects are sweet. There are many things one would want to do with a string or a number, could be great to access them as methods.
42+
- There are many things one would want to do with a string or a number, could be great to access them as methods.
6143
- Primitives must store a single value, be as fast and lightweight as possible.
6244

6345
The solution looks a little bit awkward, but here it is.
@@ -68,7 +50,7 @@ The solution looks a little bit awkward, but here it is.
6850

6951
The "object wrappers" are different for each primitive type and are named specifically: `String`, `Number`, `Boolean` and `Symbol`. Thus they provide different sets of methods.
7052

71-
For instance, a string has a method [toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns the capitalized string.
53+
For instance, let's consider the method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns the capitalized string.
7254

7355
Here's how it works:
7456

@@ -80,8 +62,8 @@ alert( str.toUpperCase() ); // HELLO
8062

8163
Simple, right? And here's what actually happens in `str.toUpperCase()`:
8264

83-
1. A special object is created which has the string value in it and also provides string methods, like `toUpperCase()`.
84-
2. The method runs and returns a new string (shown up).
65+
1. The string `str` is a primitive. So in the moment of accessing it's property a special object is created that both knows the value of the string and has useful methods, like `toUpperCase()`.
66+
2. That method runs and returns a new string (shown by `alert`).
8567
3. The special object disappears, leaving the primitive `str` alone.
8668

8769
So, primitives can provide methods, but they still remain lightweight.
@@ -110,10 +92,9 @@ An attempt to access a property of such value would give an error:
11092
alert(null.test); // error
11193
````
11294

113-
114-
11595
## Summary
11696

11797
- Primitives except `null` and `undefined` provide various methods. We plan to study those in the next sections.
11898
- Still, primitives are not objects. Formally, methods work via temporary objects that are created "just for the call". The JavaScript engines are tuned to optimize that internally, so it's not expensive at all.
11999

100+
Further we'll get back to data structures and study methods in more detail.

1-js/2-first-steps/22-javascript-specials/article.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Всё вместе: особенности JavaScript TODO
1+
# TODO: Всё вместе: особенности JavaScript
22

33
В этой главе приводятся основные особенности JavaScript, на уровне базовых конструкций, типов, синтаксиса.
44

0 commit comments

Comments
 (0)