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/01-getting-started/1-intro/article.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# An Introduction to JavaScript
2
2
3
-
Let's see what's so special about JavaScript, what we can achieve with it, and which other technologies play well with it.
3
+
Let's see what's so special about JavaScript, what we can achieve with it, and what other technologies play well with it.
4
4
5
5
## What is JavaScript?
6
6
@@ -68,7 +68,7 @@ Examples of such restrictions include:
68
68
Modern browsers allow it to work with files, but the access is limited and only provided if the user does certain actions, like "dropping" a file into a browser window or selecting it via an `<input>` tag.
69
69
70
70
There are ways to interact with camera/microphone and other devices, but they require a user's explicit permission. So a JavaScript-enabled page may not sneakily enable a web-camera, observe the surroundings and send the information to the [NSA](https://en.wikipedia.org/wiki/National_Security_Agency).
71
-
- Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other if they come from different sites (from a different domain, protocol or port).
71
+
- Different tabs/windows generally do not know about each other. Sometimes they do; for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other if they come from different sites (from a different domain, protocol or port).
72
72
73
73
This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and contain a special JavaScript code that handles it. We'll cover that in the tutorial.
74
74
@@ -116,6 +116,6 @@ There are more. Of course, even if we use one of transpiled languages, we should
116
116
117
117
## Summary
118
118
119
-
- JavaScript was initially created as a browser-only language, but is now used in many other environments as well.
120
-
- Today, JavaScript has a unique position as the most widely-adopted browser language with full integration with HTML/CSS.
119
+
- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well.
120
+
- Today, JavaScript has a unique position as the most widely-adopted browser language with full integration in HTML/CSS.
121
121
- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript.
Copy file name to clipboardExpand all lines: 1-js/02-first-steps/18-javascript-specials/article.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -144,7 +144,7 @@ Assignments
144
144
: There is a simple assignment: `a = b` and combined ones like `a *= 2`.
145
145
146
146
Bitwise
147
-
: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](mdn:/JavaScript/Reference/Operators/Bitwise_Operators) when they are needed.
147
+
: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](mdn:/JavaScript/Guide/Expressions_and_Operators#Bitwise) when they are needed.
148
148
149
149
Conditional
150
150
: The only operator with three parameters: `cond ? resultA : resultB`. If `cond` is truthy, returns `resultA`, otherwise `resultB`.
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/02-object-copy/article.md
+27-14Lines changed: 27 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,12 @@
1
-
# Object copying, references
1
+
# Object references and copying
2
2
3
-
One of the fundamental differences of objects vs primitives is that they are stored and copied "by reference".
3
+
One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", as opposed to primitive values: strings, numbers, booleans, etc -- that are always copied "as a whole value".
4
4
5
-
Primitive values: strings, numbers, booleans -- are assigned/copied "as a whole value".
5
+
That's easy to understand if we look a bit "under a cover" of what happens when we copy a value.
6
6
7
-
For instance:
7
+
Let's start with a primitive, such as a string.
8
+
9
+
Here we put a copy of `message` into `phrase`:
8
10
9
11
```js
10
12
let message ="Hello!";
@@ -15,21 +17,31 @@ As a result we have two independent variables, each one is storing the string `"
15
17
16
18

17
19
20
+
Quite an obvious result, right?
21
+
18
22
Objects are not like that.
19
23
20
-
**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.**
24
+
**A variable assigned to an object stores not the object itself, but its "address in memory", in other words "a reference" to it.**
21
25
22
-
Here's the picture for the object:
26
+
Let's look at an example of such variable:
23
27
24
28
```js
25
29
let user = {
26
30
name:"John"
27
31
};
28
32
```
29
33
34
+
And here's how it's actually stored in memory:
35
+
30
36

31
37
32
-
Here, the object is stored somewhere in memory. And the variable `user` has a "reference" to it.
38
+
The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it.
39
+
40
+
We may think of an object variable, such as `user`, as of a sheet of paper with the address.
41
+
42
+
When we perform actions with the object, e.g. take a property `user.name`, JavaScript engine looks into that address and performs the operation on the actual object.
43
+
44
+
Now here's why it's important.
33
45
34
46
**When an object variable is copied -- the reference is copied, the object is not duplicated.**
35
47
@@ -45,6 +57,8 @@ Now we have two variables, each one with the reference to the same object:
45
57
46
58

47
59
60
+
As you can see, there's still one object, now with two variables that reference it.
61
+
48
62
We can use any variable to access the object and modify its contents:
49
63
50
64
```js run
@@ -59,15 +73,14 @@ admin.name = 'Pete'; // changed by the "admin" reference
59
73
alert(*!*user.name*/!*); //'Pete', changes are seen from the "user" reference
60
74
```
61
75
62
-
The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes.
63
76
64
-
## Comparison by reference
77
+
It's just as if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes.
65
78
66
-
The equality `==` and strict equality `===` operators for objects work exactly the same.
79
+
## Comparison by reference
67
80
68
-
**Two objects are equal only if they are the same object.**
81
+
Two objects are equal only if they are the same object.
69
82
70
-
Here two variables reference the same object, thus they are equal:
83
+
For instance, here `a` and `b` reference the same object, thus they are equal:
71
84
72
85
```js run
73
86
let a = {};
@@ -77,7 +90,7 @@ alert( a == b ); // true, both variables reference the same object
77
90
alert( a === b ); // true
78
91
```
79
92
80
-
And here two independent objects are not equal, even though both are empty:
93
+
And here two independent objects are not equal, even though they look alike (both are empty):
81
94
82
95
```js run
83
96
let a = {};
@@ -86,7 +99,7 @@ let b = {}; // two independent objects
86
99
alert( a == b ); // false
87
100
```
88
101
89
-
For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj ==5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons occur very rarely, usually as a result of a coding mistake.
102
+
For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj ==5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely, usually they appear as a result of a programming mistake.
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/07-optional-chaining/article.md
+29-21Lines changed: 29 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,21 +3,25 @@
3
3
4
4
[recent browser="new"]
5
5
6
-
The optional chaining `?.` is an error-proof way to access nested object properties, even if an intermediate property doesn't exist.
6
+
The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist.
7
7
8
-
## The problem
8
+
## The "non-existing property" problem
9
9
10
10
If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common.
11
11
12
-
For example, some of our users have addresses, but few did not provide them. Then we can't safely read `user.address.street`:
12
+
As an example, let's consider objects for user data. Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them.
13
+
14
+
In such case, when we attempt to get `user.address.street`, we'll get an error:
13
15
14
16
```js run
15
-
let user = {}; // the user happens to be without address
17
+
let user = {}; // the user without "address" property
16
18
17
19
alert(user.address.street); // Error!
18
20
```
19
21
20
-
Or, in the web development, we'd like to get an information about an element on the page, but it may not exist:
22
+
That's the expected result, JavaScript works like this, but many practical cases we'd prefer to get `undefined` instead of an error (meaning "no street").
23
+
24
+
...And another example. In the web development, we may need to get an information about an element on the page, that sometimes doesn't exist:
21
25
22
26
```js run
23
27
// Error if the result of querySelector(...) is null
@@ -34,7 +38,7 @@ let user = {}; // user has no address
34
38
alert( user &&user.address&&user.address.street ); // undefined (no error)
35
39
```
36
40
37
-
AND'ing the whole path to the property ensures that all components exist, but is cumbersome to write.
41
+
AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but is cumbersome to write.
38
42
39
43
## Optional chaining
40
44
@@ -70,7 +74,7 @@ We should use `?.` only where it's ok that something doesn't exist.
70
74
71
75
For example, if according to our coding logic `user` object must be there, but `address` is optional, then `user.address?.street` would be better.
72
76
73
-
So, if`user` happens to be undefined due to a mistake, we'll know about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
77
+
So, if`user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
74
78
```
75
79
76
80
````warn header="The variable before `?.` must be declared"
@@ -80,25 +84,27 @@ If there's no variable `user` at all, then `user?.anything` triggers an error:
80
84
// ReferenceError: user is not defined
81
85
user?.address;
82
86
```
83
-
There must be `let/const/var user`. The optional chaining works only for declared variables.
87
+
There must be a declaration (e.g. `let/const/var user`). The optional chaining works only for declared variables.
84
88
````
85
89
86
90
## Short-circuiting
87
91
88
92
As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist.
89
93
90
-
So, if there are any further function calls or side effects, they don't occur:
94
+
So, if there are any further function calls or side effects, they don't occur.
95
+
96
+
For instance:
91
97
92
98
```js run
93
99
let user = null;
94
100
let x = 0;
95
101
96
-
user?.sayHi(x++); // nothing happens
102
+
user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++
97
103
98
104
alert(x); // 0, value not incremented
99
105
```
100
106
101
-
## Other cases:?.(), ?.[]
107
+
## Other variants:?.(), ?.[]
102
108
103
109
The optional chaining `?.` is not an operator, but a special syntax construct, that also works with functions and square brackets.
104
110
@@ -121,9 +127,9 @@ user2.admin?.();
121
127
*/!*
122
128
```
123
129
124
-
Here, in both lines we first use the dot `.` to get `admin` property, because the user object must exist, so it's safe read from it.
130
+
Here, in both lines we first use the dot (`user1.admin`) to get `admin` property, because the user object must exist, so it's safe read from it.
125
131
126
-
Then `?.()` checks the left part: if the admin function exists, then it runs (for `user1`). Otherwise (for `user2`) the evaluation stops without errors.
132
+
Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `user1`). Otherwise (for `user2`) the evaluation stops without errors.
127
133
128
134
The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
129
135
@@ -148,28 +154,30 @@ Also we can use `?.` with `delete`:
148
154
delete user?.name; // delete user.name if user exists
149
155
```
150
156
151
-
```warn header="We can use `?.` for safe reading and deleting, but not writing"
152
-
The optional chaining `?.` has no use at the left side of an assignment:
157
+
````warn header="We can use `?.` for safe reading and deleting, but not writing"
158
+
The optional chaining `?.` has no use at the left side of an assignment.
153
159
160
+
For example:
154
161
```js run
155
-
// the idea of the code below is to write user.name, if user exists
162
+
letuser=null;
156
163
157
164
user?.name="John"; // Error, doesn't work
158
165
// because it evaluates to undefined = "John"
159
166
```
160
167
168
+
It's just not that smart.
169
+
````
170
+
161
171
## Summary
162
172
163
-
The `?.` syntax has three forms:
173
+
The optional chaining `?.` syntax has three forms:
164
174
165
175
1. `obj?.prop` -- returns `obj.prop` if `obj` exists, otherwise `undefined`.
166
176
2. `obj?.[prop]` -- returns `obj[prop]` if `obj` exists, otherwise `undefined`.
As we can see, all of them are straightforward and simple to use. The `?.` checks the left part for `null/undefined` and allows the evaluation to proceed if it's not so.
170
180
171
181
A chain of `?.` allows to safely access nested properties.
172
182
173
-
Still, we should apply `?.` carefully, only where it's ok that the left part doesn't to exist.
174
-
175
-
So that it won't hide programming errors from us, if they occur.
183
+
Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't to exist. So that it won't hide programming errors from us, if they occur.
Copy file name to clipboardExpand all lines: 1-js/05-data-types/03-string/article.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -110,7 +110,7 @@ alert( 'I*!*\'*/!*m the Walrus!' ); // *!*I'm*/!* the Walrus!
110
110
111
111
As you can see, we have to prepend the inner quote by the backslash `\'`, because otherwise it would indicate the string end.
112
112
113
-
Of course, only to the quotes that are the same as the enclosing ones need to be escaped. So, as a more elegant solution, we could switch to double quotes or backticks instead:
113
+
Of course, only the quotes that are the same as the enclosing ones need to be escaped. So, as a more elegant solution, we could switch to double quotes or backticks instead:
114
114
115
115
```js run
116
116
alert( `I'm the Walrus!` ); // I'm the Walrus!
@@ -312,7 +312,7 @@ if (str.indexOf("Widget") != -1) {
312
312
313
313
#### The bitwise NOT trick
314
314
315
-
One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT)`~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation.
315
+
One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT)`~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation.
316
316
317
317
In practice, that means a simple thing: for 32-bit integers `~n` equals `-(n+1)`.
318
318
@@ -345,7 +345,7 @@ It is usually not recommended to use language features in a non-obvious way, but
345
345
346
346
Just remember: `if (~str.indexOf(...))` reads as "if found".
347
347
348
-
To be precise though, as big numbers are truncated to 32 bits by `~` operator, there exist other numbers that give `0`, the smallest is `~4294967295=0`. That makes such check is correct only if a string is not that long.
348
+
To be precise though, as big numbers are truncated to 32 bits by `~` operator, there exist other numbers that give `0`, the smallest is `~4294967295=0`. That makes such check correct only if a string is not that long.
349
349
350
350
Right now we can see this trick only in the old code, as modern JavaScript provides `.includes` method (see below).
0 commit comments