diff --git a/.gitignore b/.gitignore
index 6f90fd190..1a71fb7c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ sftp-config.json
Thumbs.db
+/svgs
\ No newline at end of file
diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md
index f81e52822..ff7db2f5c 100644
--- a/1-js/01-getting-started/1-intro/article.md
+++ b/1-js/01-getting-started/1-intro/article.md
@@ -24,11 +24,11 @@ The browser has an embedded engine sometimes called a "JavaScript virtual machin
Different engines have different "codenames". For example:
-- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome and Opera.
+- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome, Opera and Edge.
- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox.
- ...There are other codenames like "Chakra" for IE, "JavaScriptCore", "Nitro" and "SquirrelFish" for Safari, etc.
-The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome and Opera.
+The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome, Opera and Edge.
```smart header="How do engines work?"
@@ -59,7 +59,7 @@ For instance, in-browser JavaScript is able to:
## What CAN'T in-browser JavaScript do?
-JavaScript's abilities in the browser are limited for the sake of the user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data.
+JavaScript's abilities in the browser are limited for the sake of a user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data.
Examples of such restrictions include:
@@ -86,7 +86,7 @@ There are at least *three* great things about JavaScript:
```compare
+ Full integration with HTML/CSS.
+ Simple things are done simply.
-+ Support by all major browsers and enabled by default.
++ Supported by all major browsers and enabled by default.
```
JavaScript is the only browser technology that combines these three things.
@@ -118,5 +118,5 @@ There are more. Of course, even if we use one of transpiled languages, we should
## Summary
- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well.
-- Today, JavaScript has a unique position as the most widely-adopted browser language with full integration in HTML/CSS.
+- Today, JavaScript has a unique position as the most widely-adopted browser language, fully integrated with HTML/CSS.
- 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.
diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md
index d03f03def..6532e54a3 100644
--- a/1-js/01-getting-started/3-code-editors/article.md
+++ b/1-js/01-getting-started/3-code-editors/article.md
@@ -32,7 +32,6 @@ In practice, lightweight editors may have a lot of plugins including directory-l
The following options deserve your attention:
- [Atom](https://atom.io/) (cross-platform, free).
-- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
- [Sublime Text](http://www.sublimetext.com) (cross-platform, shareware).
- [Notepad++](https://notepad-plus-plus.org/) (Windows, free).
- [Vim](http://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them.
diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md
index fa935f341..35f82bf5d 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -73,7 +73,7 @@ Script files are attached to HTML with the `src` attribute:
```
-Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"` would mean a file `"script.js"` in the current folder.
+Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"`, just like `src="./script.js"`, would mean a file `"script.js"` in the current folder.
We can give a full URL as well. For instance:
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index 03eeaa6d0..0d5d2f30b 100644
--- a/1-js/02-first-steps/04-variables/article.md
+++ b/1-js/02-first-steps/04-variables/article.md
@@ -24,7 +24,7 @@ Now, we can put some data into it by using the assignment operator `=`:
let message;
*!*
-message = 'Hello'; // store the string
+message = 'Hello'; // store the string 'Hello' in the variable named message
*/!*
```
diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
index ead7922ff..a69317fee 100644
--- a/1-js/02-first-steps/09-comparison/article.md
+++ b/1-js/02-first-steps/09-comparison/article.md
@@ -7,7 +7,7 @@ In JavaScript they are written like this:
- Greater/less than: a > b, a < b.
- Greater/less than or equals: a >= b, a <= b.
- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment.
-- Not equals. In maths the notation is ≠, but in JavaScript it's written as a != b.
+- Not equals: In maths the notation is ≠, but in JavaScript it's written as a != b.
In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.
diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md
index eb491d9f4..24cf31420 100644
--- a/1-js/02-first-steps/11-logical-operators/article.md
+++ b/1-js/02-first-steps/11-logical-operators/article.md
@@ -123,7 +123,7 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl
It means that `||` processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument.
- That importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
+ The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
In the example below, only the second message is printed:
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
index 2579b647d..a7a211569 100644
--- a/1-js/02-first-steps/13-while-for/article.md
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -106,7 +106,7 @@ Let's examine the `for` statement part-by-part:
| part | | |
|-------|----------|----------------------------------------------------------------------------|
-| begin | `i = 0` | Executes once upon entering the loop. |
+| begin | `let i = 0` | Executes once upon entering the loop. |
| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. |
| body | `alert(i)`| Runs again and again while the condition is truthy. |
| step| `i++` | Executes after the body on each iteration. |
@@ -377,7 +377,7 @@ label: {
}
```
-...Although, 99.9% of the time `break` used is inside loops, as we've seen in the examples above.
+...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above.
A `continue` is only possible from inside a loop.
````
diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md
index ac6f1f47c..b46f42924 100644
--- a/1-js/02-first-steps/15-function-basics/article.md
+++ b/1-js/02-first-steps/15-function-basics/article.md
@@ -181,7 +181,7 @@ In other words, to put these terms straight:
We declare functions listing their parameters, then call them passing arguments.
-In the example above, one might say: "the function `sayMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
+In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
## Default values
@@ -247,7 +247,7 @@ function showMessage(text) {
showMessage(); // empty message
```
-...Or we could use the `??` operator:
+...Or we could use the `||` operator:
```js
function showMessage(text) {
diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md
index 982f41c4d..904f0a939 100644
--- a/1-js/03-code-quality/02-coding-style/article.md
+++ b/1-js/03-code-quality/02-coding-style/article.md
@@ -301,11 +301,11 @@ The great thing about them is that style-checking can also find some bugs, like
Here are some well-known linting tools:
-- [JSLint](http://www.jslint.com/) -- one of the first linters.
-- [JSHint](http://www.jshint.com/) -- more settings than JSLint.
-- [ESLint](http://eslint.org/) -- probably the newest one.
+- [JSLint](https://www.jslint.com/) -- one of the first linters.
+- [JSHint](https://jshint.com/) -- more settings than JSLint.
+- [ESLint](https://eslint.org/) -- probably the newest one.
-All of them can do the job. The author uses [ESLint](http://eslint.org/).
+All of them can do the job. The author uses [ESLint](https://eslint.org/).
Most linters are integrated with many popular editors: just enable the plugin in the editor and configure the style.
@@ -335,7 +335,7 @@ Here's an example of an `.eslintrc` file:
Here the directive `"extends"` denotes that the configuration is based on the "eslint:recommended" set of settings. After that, we specify our own.
-It is also possible to download style rule sets from the web and extend them instead. See for more details about installation.
+It is also possible to download style rule sets from the web and extend them instead. See for more details about installation.
Also certain IDEs have built-in linting, which is convenient but not as customizable as ESLint.
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 7efaf8677..02be20872 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -22,7 +22,7 @@ Here, in this chapter, our purpose is to get the gist of how they work, and thei
## Transpilers
-A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that can parse ("read and understand") modern code, and rewrite it using older syntax constructs, so that the result would be the same.
+A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that translates source code to another source code. It can parse ("read and understand") modern code and rewrite it using older syntax constructs, so that it'll also work in outdated engines.
E.g. JavaScript before year 2020 didn't have the "nullish coalescing operator" `??`. So, if a visitor uses an outdated browser, it may fail to understand the code like `height = height ?? 100`.
diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md
index cafb71cac..b56a8034b 100644
--- a/1-js/04-object-basics/02-object-copy/article.md
+++ b/1-js/04-object-basics/02-object-copy/article.md
@@ -133,7 +133,7 @@ clone.name = "Pete"; // changed the data in it
alert( user.name ); // still John in the original object
```
-Also we can use the method [Object.assign](mdn:js/Object/assign) for that.
+Also we can use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) for that.
The syntax is:
diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
index 8c1fea8eb..d80113acc 100644
--- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
+++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
@@ -4,7 +4,7 @@ importance: 2
# Two functions – one object
-Is it possible to create functions `A` and `B` such as `new A()==new B()`?
+Is it possible to create functions `A` and `B` so that `new A() == new B()`?
```js no-beautify
function A() { ... }
diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md
index b0605d44f..3e52a1d51 100644
--- a/1-js/04-object-basics/09-object-toprimitive/article.md
+++ b/1-js/04-object-basics/09-object-toprimitive/article.md
@@ -9,7 +9,7 @@ In case of such operations, objects are auto-converted to primitives, and then t
That's an important limitation, as the result of `obj1 + obj2` can't be another object!
-E.g. we can't make objects representing vectors or matrices (or archievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board".
+E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board".
So, because we can't do much here, there's no maths with objects in real projects. When it happens, it's usually because of a coding mistake.
@@ -133,7 +133,7 @@ As we can see from the code, `user` becomes a self-descriptive string or a money
If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`:
-- For the "string" hint: `toString`, and if it doesn't exist, then `valueOf` (so `toString` has the priority for stirng conversions).
+- For the "string" hint: `toString`, and if it doesn't exist, then `valueOf` (so `toString` has the priority for string conversions).
- For other hints: `valueOf`, and if it doesn't exist, then `toString` (so `valueOf` has the priority for maths).
Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
@@ -274,4 +274,4 @@ The conversion algorithm is:
In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes.
-As for math operations, JavaScript doesn't provide a way to "override" them using methods, so real life projects rarely use them on objects.
\ No newline at end of file
+As for math operations, JavaScript doesn't provide a way to "override" them using methods, so real life projects rarely use them on objects.
diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md
index 552c3b3b6..930a304f7 100644
--- a/1-js/05-data-types/01-primitives-methods/article.md
+++ b/1-js/05-data-types/01-primitives-methods/article.md
@@ -48,7 +48,7 @@ The solution looks a little bit awkward, but here it is:
2. The language allows access to methods and properties of strings, numbers, booleans and symbols.
3. In order for that to work, a special "object wrapper" that provides the extra functionality is created, and then is destroyed.
-The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean` and `Symbol`. Thus, they provide different sets of methods.
+The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods.
For instance, there exists a string method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns a capitalized `str`.
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 6fd513f43..547204b57 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -4,7 +4,7 @@ In modern JavaScript, there are two types of numbers:
1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
-2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't exceed 253 or be less than -253. As bigints are used in few special areas, we devote them a special chapter .
+2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't safely exceed 253 or be less than -253. As bigints are used in few special areas, we devote them a special chapter .
So here we'll talk about regular numbers. Let's expand our knowledge of them.
@@ -37,8 +37,8 @@ alert( 7.3e9 ); // 7.3 billions (same as 7300000000 or 7_300_000_000)
In other words, `e` multiplies the number by `1` with the given zeroes count.
```js
-1e3 = 1 * 1000 // e3 means *1000
-1.23e6 = 1.23 * 1000000 // e6 means *1000000
+1e3 === 1 * 1000; // e3 means *1000
+1.23e6 === 1.23 * 1000000; // e6 means *1000000
```
Now let's write something very small. Say, 1 microsecond (one millionth of a second):
@@ -53,16 +53,16 @@ Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes
let ms = 1e-6; // six zeroes to the left from 1
```
-If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
+If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
In other words, a negative number after `"e"` means a division by 1 with the given number of zeroes:
```js
// -3 divides by 1 with 3 zeroes
-1e-3 = 1 / 1000 (=0.001)
+1e-3 === 1 / 1000; // 0.001
// -6 divides by 1 with 6 zeroes
-1.23e-6 = 1.23 / 1000000 (=0.00000123)
+1.23e-6 === 1.23 / 1000000; // 0.00000123
```
### Hex, binary and octal numbers
@@ -118,6 +118,7 @@ Please note that two dots in `123456..toString(36)` is not a typo. If we want to
If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now goes the method.
Also could write `(123456).toString(36)`.
+
```
## Rounding
@@ -328,7 +329,7 @@ let num = +prompt("Enter a number", '');
alert( isFinite(num) );
```
-Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.
+Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.
```smart header="Compare with `Object.is`"
diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md
index 3b07eccad..41bda2254 100644
--- a/1-js/05-data-types/03-string/article.md
+++ b/1-js/05-data-types/03-string/article.md
@@ -81,7 +81,7 @@ Here's the full list:
| Character | Description |
|-----------|-------------|
|`\n`|New line|
-|`\r`|Carriage return: not used alone. Windows text files use a combination of two characters `\r\n` to represent a line break. |
+|`\r`|In Windows text files a combination of two characters `\r\n` represents a new break, while on non-Windows OS it's just `\n`. That's for historical reasons, most Windows software also understands `\n`. |
|`\'`, `\"`|Quotes|
|`\\`|Backslash|
|`\t`|Tab|
diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
index d3c8f8eb1..7f0082357 100644
--- a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
+++ b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
@@ -4,7 +4,7 @@ importance: 4
# Create keyed object from array
-Let's say we received an array of users in the form `{id:..., name:..., age... }`.
+Let's say we received an array of users in the form `{id:..., name:..., age:... }`.
Create a function `groupById(arr)` that creates an object from it, with `id` as the key, and array items as values.
diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md
index 28c48a533..bef678f53 100644
--- a/1-js/05-data-types/09-keys-values-entries/article.md
+++ b/1-js/05-data-types/09-keys-values-entries/article.md
@@ -77,7 +77,7 @@ Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others
If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`:
1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`.
-2. Use array methods on that array, e.g. `map`.
+2. Use array methods on that array, e.g. `map`, to transform these key/value pairs.
3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object.
For example, we have an object with prices, and would like to double them:
@@ -91,12 +91,13 @@ let prices = {
*!*
let doublePrices = Object.fromEntries(
- // convert to array, map, and then fromEntries gives back the object
- Object.entries(prices).map(([key, value]) => [key, value * 2])
+ // convert prices to array, map each key/value pair into another pair
+ // and then fromEntries gives back the object
+ Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
);
*/!*
alert(doublePrices.meat); // 8
-```
+```
-It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way.
+It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way.
diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
index 4357ff208..0eb76ea1c 100644
--- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
@@ -33,7 +33,7 @@ printReverseList(list);
# Using a loop
-The loop variant is also a little bit more complicated then the direct output.
+The loop variant is also a little bit more complicated than the direct output.
There is no way to get the last value in our `list`. We also can't "go back".
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
index e3c335e03..802f28c4d 100644
--- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
@@ -23,7 +23,7 @@ describe("byField", function(){
{ name: "John", age: 20, surname: "Johnson"},
];
let ageSortedAnswer = users.sort(byField("age"));
- assert.deepEqual(ageSortedKey, ageSortedKey);
+ assert.deepEqual(ageSortedKey, ageSortedAnswer);
});
it("sorts users by surname", function(){
diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md
index d433cbc5d..cade0147f 100644
--- a/1-js/06-advanced-functions/04-var/article.md
+++ b/1-js/06-advanced-functions/04-var/article.md
@@ -4,7 +4,7 @@
```smart header="This article is for understanding old scripts"
The information in this article is useful for understanding old scripts.
-That's not how we write a new code.
+That's not how we write new code.
```
In the very first chapter about [variables](info:variables), we mentioned three ways of variable declaration:
diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md
index 3cee4fe83..9d705cdcd 100644
--- a/1-js/06-advanced-functions/10-bind/article.md
+++ b/1-js/06-advanced-functions/10-bind/article.md
@@ -187,8 +187,8 @@ let user = {
let say = user.say.bind(user);
-say("Hello"); // Hello, John ("Hello" argument is passed to say)
-say("Bye"); // Bye, John ("Bye" is passed to say)
+say("Hello"); // Hello, John! ("Hello" argument is passed to say)
+say("Bye"); // Bye, John! ("Bye" is passed to say)
```
````smart header="Convenience method: `bindAll`"
diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md
index f8f8d21d4..3b72635c3 100644
--- a/1-js/07-object-properties/01-property-descriptors/article.md
+++ b/1-js/07-object-properties/01-property-descriptors/article.md
@@ -19,7 +19,7 @@ We didn't see them yet, because generally they do not show up. When we create a
First, let's see how to get those flags.
-The method [Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
+The method [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
The syntax is:
```js
@@ -54,7 +54,7 @@ alert( JSON.stringify(descriptor, null, 2 ) );
*/
```
-To change the flags, we can use [Object.defineProperty](mdn:js/Object/defineProperty).
+To change the flags, we can use [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
The syntax is:
@@ -194,7 +194,7 @@ alert(Object.keys(user)); // name
The non-configurable flag (`configurable:false`) is sometimes preset for built-in objects and properties.
-A non-configurable property can not be deleted.
+A non-configurable property can't be deleted, its attributes can't be modified.
For instance, `Math.PI` is non-writable, non-enumerable and non-configurable:
@@ -214,20 +214,23 @@ alert( JSON.stringify(descriptor, null, 2 ) );
So, a programmer is unable to change the value of `Math.PI` or overwrite it.
```js run
-Math.PI = 3; // Error
+Math.PI = 3; // Error, because it has writable: false
// delete Math.PI won't work either
```
-Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`.
+We also can't change `Math.PI` to be `writable` again:
+
+```js run
+// Error, because of configurable: false
+Object.defineProperty(Math, "PI", { writable: true });
+```
-To be precise, non-configurability imposes several restrictions on `defineProperty`:
-1. Can't change `configurable` flag.
-2. Can't change `enumerable` flag.
-3. Can't change `writable: false` to `true` (the other way round works).
-4. Can't change `get/set` for an accessor property (but can assign them if absent).
+There's absolutely nothing we can do with `Math.PI`.
-**The idea of "configurable: false" is to prevent changes of property flags and its deletion, while allowing to change its value.**
+Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`.
+
+**Please note: `configurable: false` prevents changes of property flags and its deletion, while allowing to change its value.**
Here `user.name` is non-configurable, but we can still change it (as it's writable):
@@ -244,7 +247,7 @@ user.name = "Pete"; // works fine
delete user.name; // Error
```
-And here we make `user.name` a "forever sealed" constant:
+And here we make `user.name` a "forever sealed" constant, just like the built-in `Math.PI`:
```js run
let user = {
@@ -263,10 +266,15 @@ delete user.name;
Object.defineProperty(user, "name", { value: "Pete" });
```
+```smart header="The only attribute change possible: writable true -> false"
+There's a minor exception about changing flags.
+
+We can change `writable: true` to `false` for a non-configurable property, thus preventing its value modification (to add another layer of protection). Not the other way around though.
+```
## Object.defineProperties
-There's a method [Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties) that allows to define many properties at once.
+There's a method [Object.defineProperties(obj, descriptors)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) that allows to define many properties at once.
The syntax is:
@@ -292,7 +300,7 @@ So, we can set many properties at once.
## Object.getOwnPropertyDescriptors
-To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors).
+To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors).
Together with `Object.defineProperties` it can be used as a "flags-aware" way of cloning an object:
@@ -318,24 +326,24 @@ Property descriptors work at the level of individual properties.
There are also methods that limit access to the *whole* object:
-[Object.preventExtensions(obj)](mdn:js/Object/preventExtensions)
+[Object.preventExtensions(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
: Forbids the addition of new properties to the object.
-[Object.seal(obj)](mdn:js/Object/seal)
+[Object.seal(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
: Forbids adding/removing of properties. Sets `configurable: false` for all existing properties.
-[Object.freeze(obj)](mdn:js/Object/freeze)
+[Object.freeze(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
: Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties.
And also there are tests for them:
-[Object.isExtensible(obj)](mdn:js/Object/isExtensible)
+[Object.isExtensible(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible)
: Returns `false` if adding properties is forbidden, otherwise `true`.
-[Object.isSealed(obj)](mdn:js/Object/isSealed)
+[Object.isSealed(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed)
: Returns `true` if adding/removing properties is forbidden, and all existing properties have `configurable: false`.
-[Object.isFrozen(obj)](mdn:js/Object/isFrozen)
+[Object.isFrozen(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen)
: Returns `true` if adding/removing/changing properties is forbidden, and all current properties are `configurable: false, writable: false`.
These methods are rarely used in practice.
diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md
index e26d0ec81..91efb89ee 100644
--- a/1-js/09-classes/04-private-protected-properties-methods/article.md
+++ b/1-js/09-classes/04-private-protected-properties-methods/article.md
@@ -116,7 +116,7 @@ class CoffeeMachine {
let coffeeMachine = new CoffeeMachine(100);
// add water
-coffeeMachine.waterAmount = -10; // Error: Negative water
+coffeeMachine.waterAmount = -10; // _waterAmount will become 0, not -10
```
Now the access is under control, so setting the water amount below zero becomes impossible.
diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md
index 630818188..f9db989ca 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -93,7 +93,7 @@ The algorithm of `obj instanceof Class` works roughly as follows:
alert(rabbit instanceof Animal); // true
*/!*
- // rabbit.__proto__ === Rabbit.prototype
+ // rabbit.__proto__ === Animal.prototype (no match)
*!*
// rabbit.__proto__.__proto__ === Animal.prototype (match!)
*/!*
diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md
index ff2e4c529..918289319 100644
--- a/1-js/10-error-handling/2-custom-errors/article.md
+++ b/1-js/10-error-handling/2-custom-errors/article.md
@@ -21,9 +21,9 @@ Internally, we'll use `JSON.parse`. If it receives malformed `json`, then it thr
Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field.
-Our `ValidationError` class should inherit from the built-in `Error` class.
+Our `ValidationError` class should inherit from the `Error` class.
-That class is built-in, but here's its approximate code so we can understand what we're extending:
+The `Error` class is built-in, but here's its approximate code so we can understand what we're extending:
```js
// The "pseudocode" for the built-in Error class defined by JavaScript itself
@@ -117,15 +117,15 @@ We could also look at `err.name`, like this:
// instead of (err instanceof SyntaxError)
} else if (err.name == "SyntaxError") { // (*)
// ...
-```
+```
The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.
-Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or other unknown ones) should fall through.
+Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (caused by a typo in the code or other unknown reasons) should fall through.
## Further inheritance
-The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age`). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
+The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age` instead of a number). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
```js run
class ValidationError extends Error {
diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md
index 344d92b74..8f9189ae3 100644
--- a/1-js/11-async/01-callbacks/article.md
+++ b/1-js/11-async/01-callbacks/article.md
@@ -28,7 +28,7 @@ function loadScript(src) {
}
```
-It appends to the document the new, dynamically created, tag `
diff --git a/2-ui/1-document/05-basic-dom-node-properties/article.md b/2-ui/1-document/05-basic-dom-node-properties/article.md
index fc3bf6525..aadf56ca1 100644
--- a/2-ui/1-document/05-basic-dom-node-properties/article.md
+++ b/2-ui/1-document/05-basic-dom-node-properties/article.md
@@ -25,7 +25,9 @@ The classes are:
- [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- the class for `` elements,
- [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- the class for `` elements,
- [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- the class for `` elements,
- - ...and so on, each tag has its own class that may provide specific properties and methods.
+ - ...and so on.
+
+There are many other tags with their own classes that may specific properties and methods, while some elements, such as ``, ``, `` do not have any specific properties, so they are instances of `HTMLElement` class.
So, the full set of properties and methods of a given node comes as the result of the inheritance.
@@ -128,7 +130,7 @@ For instance:
```html run
-
diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md
index 13e245ebb..b477a2811 100644
--- a/2-ui/1-document/09-size-and-scroll/article.md
+++ b/2-ui/1-document/09-size-and-scroll/article.md
@@ -116,7 +116,7 @@ function isHidden(elem) {
}
```
-Please note that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes (like an empty `