From 11860c30c25b3ef2493fcd789e55218470351309 Mon Sep 17 00:00:00 2001 From: kitiya Date: Fri, 1 Sep 2017 15:54:26 -0600 Subject: [PATCH 001/331] Update solution.md - question 2 Question 2: Changing from "true" to "false" --- .../08-comparison/1-comparison-questions/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md index e1f50ce1..5c8bd2bc 100644 --- a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md +++ b/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md @@ -13,7 +13,7 @@ null === +"\n0\n" → false Some of the reasons: 1. Obviously, true. -2. Dictionary comparison, hence true. +2. Dictionary comparison, hence false. 3. Again, dictionary comparison, first char of `"2"` is greater than the first char of `"1"`. 4. Values `null` and `undefined` equal each other only. 5. Strict equality is strict. Different types from both sides lead to false. From 8b141759903a913c1260f69fa1f96466313c02c6 Mon Sep 17 00:00:00 2001 From: kitiya Date: Sat, 2 Sep 2017 19:14:21 -0600 Subject: [PATCH 002/331] Update solution.md --- .../08-comparison/1-comparison-questions/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md index e1f50ce1..5c8bd2bc 100644 --- a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md +++ b/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md @@ -13,7 +13,7 @@ null === +"\n0\n" → false Some of the reasons: 1. Obviously, true. -2. Dictionary comparison, hence true. +2. Dictionary comparison, hence false. 3. Again, dictionary comparison, first char of `"2"` is greater than the first char of `"1"`. 4. Values `null` and `undefined` equal each other only. 5. Strict equality is strict. Different types from both sides lead to false. From 1b2755e9ec307a32660ed4df7197004aa0e6cddc Mon Sep 17 00:00:00 2001 From: Tom Gardner Date: Mon, 4 Sep 2017 18:54:24 +0200 Subject: [PATCH 003/331] reworded sentence in 05-types article.md --- 1-js/02-first-steps/05-types/article.md | 2 +- javascript-tutorial-en | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 javascript-tutorial-en diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md index dd7a3481..3e2de60a 100644 --- a/1-js/02-first-steps/05-types/article.md +++ b/1-js/02-first-steps/05-types/article.md @@ -162,7 +162,7 @@ let x; alert(x); // shows "undefined" ``` -Technically, it is possible to assign any variable to `undefined`: +Technically, it is possible to assign `undefined` to any variable: ```js run let x = 123; diff --git a/javascript-tutorial-en b/javascript-tutorial-en new file mode 160000 index 00000000..2bbf6a91 --- /dev/null +++ b/javascript-tutorial-en @@ -0,0 +1 @@ +Subproject commit 2bbf6a91dc0f3039c11dda63c728127a94fc9c58 From 7ad58a783303aaffcb6962f7df401caa024f0489 Mon Sep 17 00:00:00 2001 From: Fredrick Mgbeoma Date: Tue, 5 Sep 2017 00:21:04 +0100 Subject: [PATCH 004/331] Update article.md --- 1-js/05-data-types/09-destructuring-assignment/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/09-destructuring-assignment/article.md b/1-js/05-data-types/09-destructuring-assignment/article.md index 1eb37ebe..df553aeb 100644 --- a/1-js/05-data-types/09-destructuring-assignment/article.md +++ b/1-js/05-data-types/09-destructuring-assignment/article.md @@ -308,7 +308,7 @@ let options = { let {title, ...rest} = options; */!* -// now title="Menu", rest={height: 200, widht: 100} +// now title="Menu", rest={height: 200, width: 100} alert(rest.height); // 200 alert(rest.width); // 100 ``` @@ -389,7 +389,7 @@ The whole `options` object except `extra` that was not mentioned, is assigned to Finally, we have `width`, `height`, `item1`, `item2` and `title` from the default value. -That often happens with destructuring assignments. We have a complex object with may properties and want extract only what we need. +That often happens with destructuring assignments. We have a complex object with many properties and want to extract only what we need. Even like this: ```js From c1d419d140a6b308e2c3a82d28b003a735edb138 Mon Sep 17 00:00:00 2001 From: Fredrick Mgbeoma Date: Tue, 5 Sep 2017 16:58:50 +0100 Subject: [PATCH 005/331] Fixed typo in article Fixed typo in JSON.stringify section of the article --- 1-js/05-data-types/11-json/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/11-json/article.md b/1-js/05-data-types/11-json/article.md index 4081949e..88dd2d3f 100644 --- a/1-js/05-data-types/11-json/article.md +++ b/1-js/05-data-types/11-json/article.md @@ -36,7 +36,7 @@ JavaScript provides methods: - `JSON.stringify` to convert objects into JSON. - `JSON.parse` to convert JSON back into an object. -For instance, here's we `JSON.stringify` a student: +For instance, here we `JSON.stringify` a student: ```js run let student = { name: 'John', From a233ed2944406750fd67e25af571263024fb5a1f Mon Sep 17 00:00:00 2001 From: kitiya Date: Tue, 5 Sep 2017 15:06:07 -0600 Subject: [PATCH 006/331] Parameters section update parameter name from "next" to "text" --- 1-js/02-first-steps/14-function-basics/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/14-function-basics/article.md b/1-js/02-first-steps/14-function-basics/article.md index 35e77b03..63ae4ff0 100644 --- a/1-js/02-first-steps/14-function-basics/article.md +++ b/1-js/02-first-steps/14-function-basics/article.md @@ -150,7 +150,7 @@ showMessage('Ann', "What's up?"); // Ann: What's up? (**) */!* ``` -When the function is called in lines `(*)` and `(**)`, the given values are copied to local variables `from` and `next`. Then the function uses them. +When the function is called in lines `(*)` and `(**)`, the given values are copied to local variables `from` and `text`. Then the function uses them. Here's one more example: we have a variable `from` and pass it to the function. Please note: the function changes `from`, but the change is not seen outside, because a function always gets a copy of the value: From 0c86e0c8dbdea02df8887f569efb576975886332 Mon Sep 17 00:00:00 2001 From: kitiya Date: Thu, 7 Sep 2017 11:17:28 -0600 Subject: [PATCH 007/331] Update solution.md Math.round(63.5) should return 64, not 63. --- 1-js/05-data-types/02-number/2-why-rounded-down/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md index 2152d73d..a17a4671 100644 --- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md +++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md @@ -28,6 +28,6 @@ Note that `63.5` has no precision loss at all. That's because the decimal part ` ```js run -alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 63(rounded) -> 6.3 +alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(rounded) -> 6.4 ``` From 20aaed3f1d44c418f6e7ad22fcbe1c5471173a65 Mon Sep 17 00:00:00 2001 From: kitiya Date: Thu, 7 Sep 2017 13:47:49 -0600 Subject: [PATCH 008/331] Typo: occurences Update from "occurences" to "occurrences" --- 1-js/05-data-types/03-string/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index 0258675e..e002ae47 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -236,7 +236,7 @@ alert( str.indexOf("id") ); // 1, "id" is found at the position 1 (..idget with The optional second parameter allows us to search starting from the given position. -For instance, the first occurence of `"id"` is at position `1`. To look for the next occurence, let's start the search from position `2`: +For instance, the first occurrence of `"id"` is at position `1`. To look for the next occurrence, let's start the search from position `2`: ```js run let str = 'Widget with id'; @@ -280,7 +280,7 @@ while ((pos = str.indexOf(target, pos + 1)) != -1) { ```smart header="`str.lastIndexOf(pos)`" There is also a similar method [str.lastIndexOf(pos)](mdn:js/String/lastIndexOf) that searches from the end of a string to its beginning. -It would list the occurences in the reverse order. +It would list the occurrences in the reverse order. ``` There is a slight inconvenience with `indexOf` in the `if` test. We can't put it in the `if` like this: From 75e5f7196343b15e86ca0a1593c03134f0c95809 Mon Sep 17 00:00:00 2001 From: kitiya Date: Thu, 7 Sep 2017 13:52:41 -0600 Subject: [PATCH 009/331] Correct Type: Occurences Update another type from "occurences" to "occurrences" --- 1-js/05-data-types/03-string/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index 0258675e..e002ae47 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -236,7 +236,7 @@ alert( str.indexOf("id") ); // 1, "id" is found at the position 1 (..idget with The optional second parameter allows us to search starting from the given position. -For instance, the first occurence of `"id"` is at position `1`. To look for the next occurence, let's start the search from position `2`: +For instance, the first occurrence of `"id"` is at position `1`. To look for the next occurrence, let's start the search from position `2`: ```js run let str = 'Widget with id'; @@ -280,7 +280,7 @@ while ((pos = str.indexOf(target, pos + 1)) != -1) { ```smart header="`str.lastIndexOf(pos)`" There is also a similar method [str.lastIndexOf(pos)](mdn:js/String/lastIndexOf) that searches from the end of a string to its beginning. -It would list the occurences in the reverse order. +It would list the occurrences in the reverse order. ``` There is a slight inconvenience with `indexOf` in the `if` test. We can't put it in the `if` like this: From 5eb492e90e973c777033d2a20a50c649eada1370 Mon Sep 17 00:00:00 2001 From: Randy Syring Date: Thu, 7 Sep 2017 23:25:50 -0400 Subject: [PATCH 010/331] Clarify order of bubble/capture handlers on the target The way the edited paragraph was written, I initially thought the bubble handler on the target would be ran before the capture handler, which seemed odd. I believe this update clarifies the author's intention and describes better how the handler's actually work. --- 2-ui/2-events/02-bubbling-and-capturing/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index 6e39eae2..05da72fc 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -145,7 +145,7 @@ There are two possible values for that optional last argument: Note that while formally there are 3 phases, the 2nd phase ("target phase": the event reached the element) is not handled separately: handlers on both capturing and bubbling phases trigger at that phase. -If one puts a handler on the target element -- it triggers last on the capturing state, and first on the bubbling stage. +If one puts capturing and bubbling handlers on the target element, the capture handler triggers last in the capturing phase and the bubble handler triggers first in the bubbling phase. Let's see it in action: From c6e1e781933521e456ea9f2a85cbead69efe7fd1 Mon Sep 17 00:00:00 2001 From: kitiya Date: Fri, 8 Sep 2017 13:09:17 -0600 Subject: [PATCH 011/331] adding a back-tick ( ` ) Adding a back-tick to correct code highlighter --- .../05-array-methods/3-filter-range-in-place/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/task.md b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/task.md index a737a525..7066a51a 100644 --- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/task.md +++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/task.md @@ -4,7 +4,7 @@ importance: 4 # Filter range "in place" -Write a function `filterRangeInPlace(arr, a, b)` that gets an array `arr` and removes from it all values except those that are between `a` and `b. The test is: `a ≤ arr[i] ≤ b`. +Write a function `filterRangeInPlace(arr, a, b)` that gets an array `arr` and removes from it all values except those that are between `a` and `b`. The test is: `a ≤ arr[i] ≤ b`. The function should only modify the array. It should not return anything. From f30b0cb514c1757d6caad56393ae187ff266a453 Mon Sep 17 00:00:00 2001 From: kitiya Date: Fri, 8 Sep 2017 17:37:06 -0600 Subject: [PATCH 012/331] Update solution.md Change arr to users to match the parameter name --- 1-js/05-data-types/05-array-methods/10-average-age/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/10-average-age/solution.md b/1-js/05-data-types/05-array-methods/10-average-age/solution.md index 87bb3a94..5e19fb5a 100644 --- a/1-js/05-data-types/05-array-methods/10-average-age/solution.md +++ b/1-js/05-data-types/05-array-methods/10-average-age/solution.md @@ -1,6 +1,6 @@ ```js run function getAverageAge(users) { - return arr.reduce((prev, user) => prev + user.age, 0) / arr.length; + return users.reduce((prev, user) => prev + user.age, 0) / users.length; } let john = { name: "John", age: 25 } From c2c2c2b42a90bd5b7c040e8dabc0df856d6e3bc2 Mon Sep 17 00:00:00 2001 From: Kurczok Date: Mon, 11 Sep 2017 22:25:00 +0200 Subject: [PATCH 013/331] Missed word --- .../2-hoverintent/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md index 5c1846a9..5eedf0e6 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md @@ -44,4 +44,4 @@ The demo: If you move the mouse over the "clock" fast then nothing happens, and if you do it slow or stop on them, then there will be a tooltip. -Please note: the tooltip doesn't "blink" when the cursor between the clock subelements. +Please note: the tooltip doesn't "blink" when the cursor moves between the clock subelements. From a947264664c2c05de1c9597fdb6305b89bd9b798 Mon Sep 17 00:00:00 2001 From: kitiya Date: Tue, 12 Sep 2017 13:26:42 -0600 Subject: [PATCH 014/331] Changing 'leader' to 'user' --- 1-js/05-data-types/11-json/1-serialize-object/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/11-json/1-serialize-object/task.md b/1-js/05-data-types/11-json/1-serialize-object/task.md index cbb04609..53343e4c 100644 --- a/1-js/05-data-types/11-json/1-serialize-object/task.md +++ b/1-js/05-data-types/11-json/1-serialize-object/task.md @@ -4,7 +4,7 @@ importance: 5 # Turn the object into JSON and back -Turn the `leader` into JSON and then read it back into another variable. +Turn the `user` into JSON and then read it back into another variable. ```js let user = { From 2d4e4693f8fb3c57a03894cd96741a2cef01b4e4 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Fri, 15 Sep 2017 11:09:10 +0200 Subject: [PATCH 015/331] minor --- 2-ui/3-event-details/1-mouse-events-basics/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md index fd1c6322..de222302 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/article.md +++ b/2-ui/3-event-details/1-mouse-events-basics/article.md @@ -1,5 +1,7 @@ # Mouse events basics +Mouse events come not only from "mouse manipulators", but are also emulated on touch devices, to make them compatible. + In this chapter we'll get into more details about mouse events and their properties. [cut] @@ -26,7 +28,7 @@ The most used simple events are: ### Complex events `click` -: Triggers after `mousedown` and then `mouseup` over the same element. +: Triggers after `mousedown` and then `mouseup` over the same element if the left mouse button was used. `contextmenu` : Triggers after `mousedown` if the right mouse button was used. @@ -36,8 +38,6 @@ The most used simple events are: Complex events are made of simple ones, so in theory we could live without them. But they exist, and that's good, because they are convenient. -For touchscreen and touchpad devices mouse events also happen, they are emulated. - ### Events order An action may trigger multiple events. From 52ed864f22fbbeeb8cf1aae55a9a53bb50bd94c8 Mon Sep 17 00:00:00 2001 From: Vadim Arkadov Date: Sat, 16 Sep 2017 20:22:26 +0300 Subject: [PATCH 016/331] Wrong variables name --- 1-js/02-first-steps/07-operators/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/07-operators/article.md index 61f119b3..368e8a83 100644 --- a/1-js/02-first-steps/07-operators/article.md +++ b/1-js/02-first-steps/07-operators/article.md @@ -281,7 +281,7 @@ let a = ++counter; // (*) alert(a); // *!*2*/!* ``` -Here in the line `(*)` the prefix call `++counter` increments `i` and returns the new value that is `2`. So the `alert` shows `2`. +Here in the line `(*)` the prefix call `++counter` increments `counter` and returns the new value that is `2`. So the `alert` shows `2`. Now let's use the postfix form: @@ -292,7 +292,7 @@ let a = counter++; // (*) changed ++counter to counter++ alert(a); // *!*1*/!* ``` -In the line `(*)` the *postfix* form `counter++` also increments `i`, but returns the *old* value (prior to increment). So the `alert` shows `1`. +In the line `(*)` the *postfix* form `counter++` also increments `counter`, but returns the *old* value (prior to increment). So the `alert` shows `1`. To summarize: From d937a2255dfcf8fba12dcf4059ed184d3947ab77 Mon Sep 17 00:00:00 2001 From: Azeem Ansar Date: Sat, 16 Sep 2017 15:11:50 -0400 Subject: [PATCH 017/331] Update article.md - Change wording in first paragraph, and break out examples into numbered bullets. - Change some articles and words to make sentences clearer and more consistent. --- 1-js/02-first-steps/04-variables/article.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index 9c4c9642..fe50cc52 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -1,8 +1,10 @@ # Variables -Most of the time, a script needs to work with information. If it's an online-shop -- that's going to be the goods and a shopping cart. If it's a chat -- users, messages and so on. +Most of the time, a JavaScript application needs to work with information. Here are 2 examples: +1. An online-shop -- the information might include goods being sold and a shopping cart. +2. A chat application -- the information might include users, messages, and much more. -Variables are used to store the information. +Variables are used to store this information. [cut] @@ -296,7 +298,7 @@ Please name the variables sensibly. Take time to think if needed. Variable naming is one of the most important and complex skills in programming. A quick glance at variable names can reveal which code is written by a beginner and which by an experienced developer. -In a real project, most of the time is spent on modifying and extending the existing code base, rather than writing something completely separate from the scratch. And when we return to the code after some time of doing something else, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names. +In a real project, most of the time is spent on modifying and extending the existing code base, rather than writing something completely separate from scratch. And when we return to the code after some time of doing something else, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names. Please spend some time thinking about the right name for a variable before declaring it. That will repay you a lot. @@ -305,14 +307,14 @@ Some good-to-follow rules are: - Use human-readable names like `userName` or `shoppingCart`. - Stay away from abbreviations or short names like `a`, `b`, `c`, unless you really know what you're doing. - Make the name maximally descriptive and concise. Examples of bad names are `data` and `value`. Such a name says nothing. It is only ok to use them if it's exceptionally obvious from the context which data or value is meant. -- Agree on terms within the team and in your own mind. If a site visitor is called a "user" then we should name related variables like `currentUser` or `newUser`, but not `currentVisitor` or a `newManInTown`. +- Agree on terms within your team and in your own mind. If a site visitor is called a "user" then we should name related variables like `currentUser` or `newUser`, but not `currentVisitor` or a `newManInTown`. Sounds simple? Indeed it is, but creating good descriptive-and-concise names in practice is not. Go for it. ```smart header="Reuse or create?" And the last note. There are some lazy programmers who, instead of declaring a new variable, tend to reuse the existing ones. -As the result, the variable is like a box where people throw different things without changing the sticker. What is inside it now? Who knows... We need to come closer and check. +As a result, the variable is like a box where people throw different things without changing the sticker. What is inside it now? Who knows... We need to come closer and check. Such a programmer saves a little bit on variable declaration, but loses ten times more on debugging the code. From c17003f4fe94cea5ac703878595cabb60206087f Mon Sep 17 00:00:00 2001 From: Franz Geiger Date: Sat, 16 Sep 2017 22:06:20 +0200 Subject: [PATCH 018/331] Fix: Wrong name for Firefox JavaScript engine Gecko is the layout engine of Firefox. The JavaScript engine is called SpiderMonkey --- 1-js/01-getting-started/1-intro/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md index 74521076..1e2e97d7 100644 --- a/1-js/01-getting-started/1-intro/article.md +++ b/1-js/01-getting-started/1-intro/article.md @@ -25,7 +25,7 @@ The browser has an embedded engine, sometimes it's also called a "JavaScript vir Different engines have different "codenames", for example: - [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome and Opera. -- [Gecko](https://en.wikipedia.org/wiki/Gecko_(software)) -- in Firefox. +- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox. - ...There are other codenames like "Trident", "Chakra" for different versions of IE, "ChakraCore" for Microsoft Edge, "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. From cc4d10896e16ec0352ff38e2130dcd6a139a4f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1mal=20Rasmussen?= Date: Sun, 17 Sep 2017 00:17:25 +0200 Subject: [PATCH 019/331] Fix computed property example I'm sure the fruit variable was supposed to be used somewhere. --- 1-js/04-object-basics/01-object/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index ce86f7fb..abb93ea4 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -189,7 +189,7 @@ We can use more complex expressions inside square brackets: ```js let fruit = 'apple'; let bag = { - ['apple' + 'Computers']: 5 // bag.appleComputers = 5 + [fruit + 'Computers']: 5 // bag.appleComputers = 5 }; ``` From f77bbdddb730979b13e3d70a9dbca71809daa93f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 11:12:31 +0200 Subject: [PATCH 020/331] license --- LICENSE.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..f688d8a7 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,16 @@ + +# Attribution-NonCommercial-ShareAlike 4.0 + +The full license text is at . + +You are free to: +- **Share** – copy and redistribute the tutorial in any medium or material. +- **Adapt** – remix, transform, and build upon the material. + +Under the following terms: + +- **Attribution** — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. +- **NonCommercial** — You may not use the material for commercial purposes. +- **ShareAlike** — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. + +**To use the tutorial commercially, like printing a book and selling it, please get an approval.** From 209c457232b7e50e6b6180aab3a19ca47453b3db Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 11:12:34 +0200 Subject: [PATCH 021/331] minor --- 1-js/02-first-steps/01-hello-world/article.md | 137 ------------------ 1 file changed, 137 deletions(-) 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 e69a25f0..e69de29b 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -1,137 +0,0 @@ -# Hello, world! - -The tutorial that you're reading is about core JavaScript, which is platform-independent. Further on, you will learn Node.JS and other platforms that use it. - -But, we need a working environment to run our scripts, and, just because this book is online, the browser is a good choice. We'll keep the amount of browser-specific commands (like `alert`) to a minimum, so that you don't spend time on them if you plan to concentrate on another environment like Node.JS. On the other hand, browser details are explained in detail in the [next part](/ui) of the tutorial. - -So first, let's see how to attach a script to a webpage. For server-side environments, you can just execute it with a command like `"node my.js"` for Node.JS. - - -[cut] - -## The "script" tag - -JavaScript programs can be inserted in any part of an HTML document with the help of the ` -*/!* - -

...After the script.

- - - - -``` - -```online -You can run the example by clicking on the "Play" button in its right-top corner. -``` - -The ` - ``` - - These comments were supposed to hide the code from an old browser that didn't know about a ` -``` - -Here `/path/to/script.js` is an absolute path to the file with the script (from the site root). - -It is also possible to provide a path relative to the current page. For instance, `src="script.js"` would mean a file `"script.js"` in the current folder. - -We can give a full URL as well, for instance: - -```html - -``` - -To attach several scripts, use multiple tags: - -```html - - -… -``` - -```smart -As a rule, only the simplest scripts are put into HTML. More complex ones reside in separate files. - -The benefit of a separate file is that the browser will download it and then store in its [cache](https://en.wikipedia.org/wiki/Web_cache). - -After this, other pages that want the same script will take it from the cache instead of downloading it. So the file is actually downloaded only once. - -That saves traffic and makes pages faster. -``` - -````warn header="If `src` is set, the script content is ignored." -A single ` -``` - -We must choose: either it's an external ` - -``` -```` - -## Summary - -- We can use a ``. - - -There is much more to learn about browser scripts and their interaction with the web-page. But let's keep in mind that this part of the tutorial is devoted to the JavaScript language, so we shouldn't distract ourselves from it. We'll be using a browser as a way to run JavaScript, which is very convenient for online reading, but yet one of many. From 7898fc377dfd7f44ad27876f6fdf72fc558a3902 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 11:13:20 +0200 Subject: [PATCH 022/331] cleanup --- javascript-tutorial-en | 1 - 1 file changed, 1 deletion(-) delete mode 160000 javascript-tutorial-en diff --git a/javascript-tutorial-en b/javascript-tutorial-en deleted file mode 160000 index 2bbf6a91..00000000 --- a/javascript-tutorial-en +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2bbf6a91dc0f3039c11dda63c728127a94fc9c58 From 8ec21907a2c04be4c3233ab5b8c5de11a95784c3 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 11:14:19 +0200 Subject: [PATCH 023/331] minor --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index f688d8a7..83b113c1 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -13,4 +13,4 @@ Under the following terms: - **NonCommercial** — You may not use the material for commercial purposes. - **ShareAlike** — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. -**To use the tutorial commercially, like printing a book and selling it, please get an approval.** +To use the tutorial commercially, like printing a book and selling it, please get an approval. From e679f0da5bf2af134923fd59b96ec90aa8c8d8b6 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 11:16:11 +0200 Subject: [PATCH 024/331] clarifications --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f0565f5..2cb66d42 100755 --- a/README.md +++ b/README.md @@ -3,10 +3,13 @@ This repository hosts the content of the Modern JavaScript Tutorial, published at [https://javascript.info](https://javascript.info). -Other languages: +## Translactions + - Russian: [https://github.com/iliakan/javascript-tutorial-ru](https://github.com/iliakan/javascript-tutorial-ru). - Chinese: the ongoing translation at [https://github.com/iliakan/javascript-tutorial-cn](https://github.com/iliakan/javascript-tutorial-cn), go ahead and join if you know Chinese. +If you'd like to translate it into your language then fork the English tutorial and go ahead. I can publish the translation with your credits on a domain like fr.javascript.info, or you can do it yourself. + Please use this repository to file issues and suggest PRs for the text. ## Structure From ba0e4df492a26dbd2f6de5ca2bdeb42fc711458a Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 11:17:11 +0200 Subject: [PATCH 025/331] clarifications --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cb66d42..bf32902e 100755 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository hosts the content of the Modern JavaScript Tutorial, published a - Russian: [https://github.com/iliakan/javascript-tutorial-ru](https://github.com/iliakan/javascript-tutorial-ru). - Chinese: the ongoing translation at [https://github.com/iliakan/javascript-tutorial-cn](https://github.com/iliakan/javascript-tutorial-cn), go ahead and join if you know Chinese. -If you'd like to translate it into your language then fork the English tutorial and go ahead. I can publish the translation with your credits on a domain like fr.javascript.info, or you can do it yourself. +If you'd like to translate it into your language then fork the English tutorial and go ahead. I can publish the translation with your credits on a domain like fr.javascript.info. Please use this repository to file issues and suggest PRs for the text. From 42d9eb156325d9b1004aa39b5a3051151fdaf1a4 Mon Sep 17 00:00:00 2001 From: Mark Date: Sun, 17 Sep 2017 19:47:26 +0300 Subject: [PATCH 026/331] Update article.md Typo - miss closing parenthesis in add.map() example --- 1-js/05-data-types/05-array-methods/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md index 26163457..b5a4075b 100644 --- a/1-js/05-data-types/05-array-methods/article.md +++ b/1-js/05-data-types/05-array-methods/article.md @@ -316,7 +316,7 @@ The syntax is: ```js let result = arr.map(function(item, index, array) { // returns the new value instead of item -} +}) ``` It calls the function for each element of the array and returns the array of results. From 9bf0153f7055a5de602f501a606a6aaec3fae7dc Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Sep 2017 19:44:37 +0200 Subject: [PATCH 027/331] minor --- 1-js/02-first-steps/01-hello-world/article.md | 137 ++++++++++++++++++ .../2-custom-errors/article.md | 2 +- 2 files changed, 138 insertions(+), 1 deletion(-) 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 e69de29b..e69a25f0 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -0,0 +1,137 @@ +# Hello, world! + +The tutorial that you're reading is about core JavaScript, which is platform-independent. Further on, you will learn Node.JS and other platforms that use it. + +But, we need a working environment to run our scripts, and, just because this book is online, the browser is a good choice. We'll keep the amount of browser-specific commands (like `alert`) to a minimum, so that you don't spend time on them if you plan to concentrate on another environment like Node.JS. On the other hand, browser details are explained in detail in the [next part](/ui) of the tutorial. + +So first, let's see how to attach a script to a webpage. For server-side environments, you can just execute it with a command like `"node my.js"` for Node.JS. + + +[cut] + +## The "script" tag + +JavaScript programs can be inserted in any part of an HTML document with the help of the ` +*/!* + +

...After the script.

+ + + + +``` + +```online +You can run the example by clicking on the "Play" button in its right-top corner. +``` + +The ` + ``` + + These comments were supposed to hide the code from an old browser that didn't know about a ` +``` + +Here `/path/to/script.js` is an absolute path to the file with the script (from the site root). + +It is also possible to provide a path relative to the current page. For instance, `src="script.js"` would mean a file `"script.js"` in the current folder. + +We can give a full URL as well, for instance: + +```html + +``` + +To attach several scripts, use multiple tags: + +```html + + +… +``` + +```smart +As a rule, only the simplest scripts are put into HTML. More complex ones reside in separate files. + +The benefit of a separate file is that the browser will download it and then store in its [cache](https://en.wikipedia.org/wiki/Web_cache). + +After this, other pages that want the same script will take it from the cache instead of downloading it. So the file is actually downloaded only once. + +That saves traffic and makes pages faster. +``` + +````warn header="If `src` is set, the script content is ignored." +A single ` +``` + +We must choose: either it's an external ` + +``` +```` + +## Summary + +- We can use a ``. + + +There is much more to learn about browser scripts and their interaction with the web-page. But let's keep in mind that this part of the tutorial is devoted to the JavaScript language, so we shouldn't distract ourselves from it. We'll be using a browser as a way to run JavaScript, which is very convenient for online reading, but yet one of many. diff --git a/1-js/08-error-handling/2-custom-errors/article.md b/1-js/08-error-handling/2-custom-errors/article.md index d7a780f6..d7d61166 100644 --- a/1-js/08-error-handling/2-custom-errors/article.md +++ b/1-js/08-error-handling/2-custom-errors/article.md @@ -224,7 +224,7 @@ The code which calls `readUser` should handle these errors. Right now it uses mu Often the answer is "No": the outer code wants to be "one level above all that". It wants to have some kind of "data reading error". Why exactly it happened -- is often irrelevant (the error message describes it). Or, even better if there is a way to get error details, but only if we need to. -So let's make a new class `ReadError` to represent such errors. If an error occurs inside `readUser`, we'll catch it there and generate `ReadError`. We'll also keep the reference to the original error in the `cause` property. Then the outer code will only have to check for `ReadError`. +So let's make a new class `ReadError` to represent such errors. If an error occurs inside `readUser`, we'll catch it there and generate `ReadError`. We'll also keep the reference to the original error in its `cause` property. Then the outer code will only have to check for `ReadError`. Here's the code that defines `ReadError` and demonstrates its use in `readUser` and `try..catch`: From 19f7aa4ae5f1940a0678c6b618f9b84b367ab63e Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 18 Sep 2017 00:00:38 +0300 Subject: [PATCH 028/331] Typo - miss letter 't' Typo - miss 't', word 'between' in description arr.join() method --- 1-js/05-data-types/05-array-methods/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md index b5a4075b..d61a4a97 100644 --- a/1-js/05-data-types/05-array-methods/article.md +++ b/1-js/05-data-types/05-array-methods/article.md @@ -472,7 +472,7 @@ alert( str.split('') ); // t,e,s,t ``` ```` -The call [arr.join(str)](mdn:js/Array/join) does the reverse to `split`. It creates a string of `arr` items glued by `str` beween them. +The call [arr.join(str)](mdn:js/Array/join) does the reverse to `split`. It creates a string of `arr` items glued by `str` between them. For instance: From 3bc6f044b41cd1c1f9692307392997fb5c7d9a59 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Mon, 18 Sep 2017 01:47:39 +0200 Subject: [PATCH 029/331] Update LICENSE.md --- LICENSE.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 83b113c1..60f06924 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -12,5 +12,3 @@ Under the following terms: - **Attribution** — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - **NonCommercial** — You may not use the material for commercial purposes. - **ShareAlike** — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. - -To use the tutorial commercially, like printing a book and selling it, please get an approval. From 2b166e94473084b32dc2d3cf0b4bd254e1daba1b Mon Sep 17 00:00:00 2001 From: Micah Stubbs Date: Sun, 17 Sep 2017 17:12:54 -0700 Subject: [PATCH 030/331] Reggie --> Reggae https://en.wikipedia.org/wiki/Reggae --- 1-js/05-data-types/04-array/2-create-array/task.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md index e6dab6a9..3e930079 100644 --- a/1-js/05-data-types/04-array/2-create-array/task.md +++ b/1-js/05-data-types/04-array/2-create-array/task.md @@ -10,7 +10,7 @@ Let's try 5 array operations. 2. Append "Rock-n-Roll" to the end. 3. Replace the value in the middle by "Classics". Your code for finding the middle value should work for any arrays with odd length. 4. Strip off the first value of the array and show it. -5. Prepend `Rap` and `Reggie` to the array. +5. Prepend `Rap` and `Reggae` to the array. The array in the process: @@ -19,6 +19,6 @@ Jazz, Blues Jazz, Bues, Rock-n-Roll Jazz, Classics, Rock-n-Roll Classics, Rock-n-Roll -Rap, Reggie, Classics, Rock-n-Roll +Rap, Reggae, Classics, Rock-n-Roll ``` From ac8ea0d37261823be41e9930ad0d80b833128e51 Mon Sep 17 00:00:00 2001 From: Stepan Ivanov Date: Mon, 18 Sep 2017 14:36:13 +1100 Subject: [PATCH 031/331] typo fix --- .../07-object-oriented-programming/08-class-patterns/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/07-object-oriented-programming/08-class-patterns/article.md b/1-js/07-object-oriented-programming/08-class-patterns/article.md index d548e20d..b27203d0 100644 --- a/1-js/07-object-oriented-programming/08-class-patterns/article.md +++ b/1-js/07-object-oriented-programming/08-class-patterns/article.md @@ -5,7 +5,7 @@ In object-oriented programming, a *class* is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). ``` -There's a special syntax construct and a keyword `class` in JavaScript. But before studying it, we should consider that the term "class" comes the theory of object-oriented programming. The definition is cited above, and it's language-independant. +There's a special syntax construct and a keyword `class` in JavaScript. But before studying it, we should consider that the term "class" comes from the theory of object-oriented programming. The definition is cited above, and it's language-independant. In JavaScript there are several well-known programming patterns to make classes even without using the `class` keyword. And here we'll talk about them first. From edbe004061c54943354cd222101493d29a6cf31d Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Mon, 18 Sep 2017 09:04:07 +0200 Subject: [PATCH 032/331] readability --- .../15-function-expressions-arrows/article.md | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/1-js/02-first-steps/15-function-expressions-arrows/article.md b/1-js/02-first-steps/15-function-expressions-arrows/article.md index eca7019b..f558ca01 100644 --- a/1-js/02-first-steps/15-function-expressions-arrows/article.md +++ b/1-js/02-first-steps/15-function-expressions-arrows/article.md @@ -135,13 +135,11 @@ function showCancel() { ask("Do you agree?", showOk, showCancel); ``` -Before we explore how we can write it in a much shorter way, let's note that in the browser (and on the server-side in some cases) such functions are quite popular. +Before we explore how we can write it in a much shorter way, let's note that in the browser (and on the server-side in some cases) such functions are quite popular. The major difference between a real-life implementation and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such a function usually draws a nice-looking question window. But that's another story. -The major difference between a real-life implementation and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such a function usually draws a nice-looking question window. But that's another story. +**The arguments of `ask` are called *callback functions* or just *callbacks*.** -**The arguments of `ask` are called *callback functions* or just *callbacks*. The idea is that we pass a function and expect it to be "called back" in certain circumstances.** - -So, `showOk` becomes the callback for the "yes" answer, and `showCancel` for the "no" answer. +The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for the "yes" answer, and `showCancel` for the "no" answer. We can use Function Expressions to write the same function much shorter: @@ -160,6 +158,7 @@ ask( */!* ``` + Here, functions are declared right inside the `ask(...)` call. They have no name, and so are called *anonymous*. Such functions are not accessible outside of `ask` (because they are not assigned to variables), but that's just what we want here. Such code appears in our scripts very naturally, it's in the spirit of JavaScript. @@ -242,10 +241,7 @@ let sayHi = function(name) { // (*) no magic any more Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late. - -### Function Declaration in a block - -When a Function Declaration is made within a code block, it is visible everywhere inside that block. But not outside of it. +**When a Function Declaration is made within a code block, it is visible everywhere inside that block. But not outside of it.** Sometimes that's handy to declare a local function only needed in that block alone. But that feature may also cause problems. @@ -256,6 +252,7 @@ The code below doesn't work: ```js run let age = prompt("What is your age?", 18); +// conditionally declare a function if (age < 18) { function welcome() { @@ -270,14 +267,15 @@ if (age < 18) { } +// ...use it later *!* welcome(); // Error: welcome is not defined */!* ``` -A Function Declaration is only visible inside the code block in which it resides. +That's because a Function Declaration is only visible inside the code block in which it resides. -We can call it from within the block, but not from outside: +Here's another example: ```js run let age = 16; // take 16 as an example @@ -296,11 +294,10 @@ if (age < 18) { */!* } else { - // \ - function welcome() { // | - alert("Greetings!"); // | if age=16, the the execution does not go here, - } // | so this "welcome" is never created - // / + + function welcome() { // for age = 16, this "welcome" is never created + alert("Greetings!"); + } } // Here we're out of figure brackets, @@ -313,7 +310,9 @@ welcome(); // Error: welcome is not defined What can we do to make `welcome` visible outside of `if`? -The correct approach would be to use a Function Expression and assign `welcome` to the variable that is declared outside of `if` and has the proper visibility: +The correct approach would be to use a Function Expression and assign `welcome` to the variable that is declared outside of `if` and has the proper visibility. + +Now it works as intended: ```js run let age = prompt("What is your age?", 18); @@ -354,7 +353,7 @@ welcome(); // ok now ``` -```smart header="What to choose: Function Declaration or Function Expression?" +```smart header="When to choose Function Declaration versus Function Expression?" As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax, the one we used before. It gives more freedom in how to organize our code, because we can call such functions before they are declared. It's also a little bit easier to look up `function f(…) {…}` in the code than `let f = function(…) {…}`. Function Declarations are more "eye-catching". @@ -365,7 +364,7 @@ It's also a little bit easier to look up `function f(…) {…}` in the code tha ## Arrow functions [#arrow-functions] -There's one more very simple and concise syntax for creating functions. It's called "arrow functions", because it looks like this: +There's one more very simple and concise syntax for creating functions, that's often better than Function Expressions. It's called "arrow functions", because it looks like this: ```js @@ -382,22 +381,22 @@ let func = function(arg1, arg2, ...argN) { } ``` -...But much shorter. +...But much more concise. Let's see an example: ```js run let sum = (a, b) => a + b; -alert( sum(1, 2) ); // 3 -``` +/* The arrow function is a shorter form of: -Here the arrow function is a shorter form of: - -```js let sum = function(a, b) { return a + b; }; +*/ + +alert( sum(1, 2) ); // 3 + ``` If we have only one argument, then parentheses can be omitted, making that even shorter: @@ -412,7 +411,7 @@ let double = n => n*2; alert( double(3) ); // 6 ``` -If there are no arguments, we can insert empty parentheses: +If there are no arguments, parentheses should be empty (but they should be present): ```js run let sayHi = () => alert("Hello!"); @@ -434,9 +433,9 @@ let welcome = (age < 18) ? welcome(); // ok now ``` -The syntax may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure. +Arrow functions may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure. -Arrow functions are very convenient for simple one-line actions, when we're just too lazy to write many words. +They are very convenient for simple one-line actions, when we're just too lazy to write many words. ```smart header="Multiline arrow functions" From 2e72eed4f4bab18f49dbf408cce8f9bc42556091 Mon Sep 17 00:00:00 2001 From: Alex Zvorygin Date: Mon, 18 Sep 2017 15:30:23 -0400 Subject: [PATCH 033/331] fix typo, add relevant emoji --- 1-js/05-data-types/03-string/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index e002ae47..c0e7a7e4 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -89,7 +89,7 @@ Examples with unicode: ```js run alert( "\u00A9" ); // © alert( "\u{20331}" ); // 𠌱, a rare chinese hieroglyph (long unicode) -alert( "\u{1F60D}"); // a smiling face sumbol (another long unicode) +alert( "\u{1F60D}"); // 😍, a smiling face symbol (another long unicode) ``` All special characters start with a backslash character `\`. It is also called an "escape character". From 9d28a4c3e9bd6f264cd23ce40be593a84b9d63e3 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 18 Sep 2017 23:10:36 +0300 Subject: [PATCH 034/331] Typo - miss ')' Typo - miss ')' for closing parentheses of map method, line 46 --- 1-js/05-data-types/05-array-methods/7-map-objects/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/7-map-objects/solution.md b/1-js/05-data-types/05-array-methods/7-map-objects/solution.md index 5e9b815f..9085b631 100644 --- a/1-js/05-data-types/05-array-methods/7-map-objects/solution.md +++ b/1-js/05-data-types/05-array-methods/7-map-objects/solution.md @@ -43,7 +43,7 @@ Here JavaScript would treat `{` as the start of function body, not the start of let usersMapped = users.map(user => *!*({*/!* fullName: `${user.name} ${user.surname}`, id: user.id -}); +})); ``` Now fine. From 67b3d45296ebdba5b2341b8e5f44581efb54bbf7 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 18 Sep 2017 23:18:22 +0300 Subject: [PATCH 035/331] Typo - extra letter 'l' before calling function --- 1-js/05-data-types/05-array-methods/8-sort-objects/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/8-sort-objects/task.md b/1-js/05-data-types/05-array-methods/8-sort-objects/task.md index 935c27fc..e423f57a 100644 --- a/1-js/05-data-types/05-array-methods/8-sort-objects/task.md +++ b/1-js/05-data-types/05-array-methods/8-sort-objects/task.md @@ -15,7 +15,7 @@ let mary = { name: "Mary", age: 28 } let arr = [ john, pete, mary ]; -lsortByName(arr); +sortByName(arr); // now: [john, mary, pete] alert(arr[1].name) // Mary From 3f98c72385a48c6e80aca9682792e39c7e74c481 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 18 Sep 2017 23:43:06 +0300 Subject: [PATCH 036/331] Typo - expected ')' Typo - expected ')' for 'if' construction condition --- 1-js/05-data-types/05-array-methods/11-array-unique/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/05-array-methods/11-array-unique/solution.md b/1-js/05-data-types/05-array-methods/11-array-unique/solution.md index 5b565d42..8f7fd9af 100644 --- a/1-js/05-data-types/05-array-methods/11-array-unique/solution.md +++ b/1-js/05-data-types/05-array-methods/11-array-unique/solution.md @@ -7,7 +7,7 @@ function unique(arr) { let result = []; for (let str of arr) { - if (!result.includes(str) { + if (!result.includes(str)) { result.push(str); } } From c4b905b5835c40c145d00df916d22927fd3994c2 Mon Sep 17 00:00:00 2001 From: Alexander Scheid-Rehder Date: Tue, 19 Sep 2017 11:38:19 +0200 Subject: [PATCH 037/331] Fix typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf32902e..2943025a 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This repository hosts the content of the Modern JavaScript Tutorial, published at [https://javascript.info](https://javascript.info). -## Translactions +## Translations - Russian: [https://github.com/iliakan/javascript-tutorial-ru](https://github.com/iliakan/javascript-tutorial-ru). - Chinese: the ongoing translation at [https://github.com/iliakan/javascript-tutorial-cn](https://github.com/iliakan/javascript-tutorial-cn), go ahead and join if you know Chinese. From 17154c48c7d8cab4b90d785a8dcea2415ffde588 Mon Sep 17 00:00:00 2001 From: Alex Zvorygin Date: Tue, 19 Sep 2017 13:22:03 -0400 Subject: [PATCH 038/331] probable typo fixed --- 1-js/06-advanced-functions/03-closure/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 015f3032..0c718aad 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -358,7 +358,7 @@ Here's what's going on in the `makeCounter` example step-by-step, follow it to m Please note how memory management works here. When `makeCounter()` call finished some time ago, its Lexical Environment was retained in memory, because there's a nested function with `[[Environment]]` referencing it. - Generally, a Lexical Environment object lives until there is a function which may use it. And when there are none, it is cleared. + Generally, a Lexical Environment object lives as long as there is a function which may use it. And when there are none, it is cleared. 6. The call to `counter()` not only returns the value of `count`, but also increases it. Note that the modification is done "in place". The value of `count` is modified exactly in the environment where it was found. From 044ff6f100c5a5816d6078501e0679f7b999c3b8 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Tue, 19 Sep 2017 21:19:00 +0200 Subject: [PATCH 039/331] fix --- 1-js/05-data-types/03-string/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index c0e7a7e4..dfa2fc25 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -88,7 +88,7 @@ Examples with unicode: ```js run alert( "\u00A9" ); // © -alert( "\u{20331}" ); // 𠌱, a rare chinese hieroglyph (long unicode) +alert( "\u{20331}" ); // 佫, a rare chinese hieroglyph (long unicode) alert( "\u{1F60D}"); // 😍, a smiling face symbol (another long unicode) ``` From d7eea92b4ea6f9c6048a49c042ce950ca53b4552 Mon Sep 17 00:00:00 2001 From: "Majid H.Fard" Date: Wed, 20 Sep 2017 14:53:43 +0430 Subject: [PATCH 040/331] Update article.md --- 1-js/06-advanced-functions/01-recursion/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md index 6995cdc4..1dedd228 100644 --- a/1-js/06-advanced-functions/01-recursion/article.md +++ b/1-js/06-advanced-functions/01-recursion/article.md @@ -289,7 +289,7 @@ Recursion can give a shorter code, easier to understand and support. Optimizatio Another great application of the recursion is a recursive traversal. -Imagine, we have an company. The staff structure can be presented as an object: +Imagine, we have a company. The staff structure can be presented as an object: ```js let company = { From 67790aa261a4b63f2ac34d75974fe8697eaa1a8c Mon Sep 17 00:00:00 2001 From: Alex Zvorygin Date: Wed, 20 Sep 2017 11:52:58 -0400 Subject: [PATCH 041/331] change incorrect variable name solution and problem statement have the calls stored in `calls`, not `log` --- .../09-call-apply-decorators/01-spy-decorator/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/solution.md index 4a79d3e1..19a07201 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/solution.md @@ -1 +1 @@ -Here we can use `log.push(args)` to store all arguments in the log and `f.apply(this, args)` to forward the call. +Here we can use `calls.push(args)` to store all arguments in the log and `f.apply(this, args)` to forward the call. From 4b8f153f6d5bcaed1a63d24e377ef6274d24642d Mon Sep 17 00:00:00 2001 From: Felipe Lerma Date: Thu, 21 Sep 2017 11:13:58 -0700 Subject: [PATCH 042/331] Typo Fix on '1. Watch' section. Removed a double 'in in' on the '1. Watch...' section. --- 1-js/03-code-quality/01-debugging-chrome/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md index 14efb9a5..9c81d2dc 100644 --- a/1-js/03-code-quality/01-debugging-chrome/article.md +++ b/1-js/03-code-quality/01-debugging-chrome/article.md @@ -101,7 +101,7 @@ Please open the informational dropdowns to the right (labeled with arrows). They 1. **`Watch` -- shows current values for any expressions.** - You can click the plus `+` and input an expression. The debugger will show its value at any moment, automatically recalculating it in in the process of execution. + You can click the plus `+` and input an expression. The debugger will show its value at any moment, automatically recalculating it in the process of execution. 2. **`Call Stack` -- shows the nested calls chain.** From e0e4f67da0c094145c74b336e2a44c976701e98e Mon Sep 17 00:00:00 2001 From: Tovieye Moses Ozi Date: Sat, 23 Sep 2017 15:44:47 +0100 Subject: [PATCH 043/331] Update article.md --- 6-async/03-promise-chaining/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6-async/03-promise-chaining/article.md b/6-async/03-promise-chaining/article.md index 41acc387..612dabf1 100644 --- a/6-async/03-promise-chaining/article.md +++ b/6-async/03-promise-chaining/article.md @@ -49,7 +49,7 @@ As the result is passed along the chain of handlers, we can see a sequence of `a ![](promise-then-chain.png) -The whole thing works, because a call to `promise.then` returns a promise, so that we can call next `.then` on it. +The whole thing works, because a call to `promise.then` returns a promise, so that we can call the next `.then` on it. When a handler returns a value, it becomes the result of that promise, so the next `.then` is called with it. From 6085d981dfe5281231906020ddf1e3b489c49bf9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 24 Sep 2017 00:38:49 +0300 Subject: [PATCH 044/331] Fix spaces around operator --- 1-js/02-first-steps/15-function-expressions-arrows/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/02-first-steps/15-function-expressions-arrows/article.md b/1-js/02-first-steps/15-function-expressions-arrows/article.md index f558ca01..a7a840d0 100644 --- a/1-js/02-first-steps/15-function-expressions-arrows/article.md +++ b/1-js/02-first-steps/15-function-expressions-arrows/article.md @@ -403,9 +403,9 @@ If we have only one argument, then parentheses can be omitted, making that even ```js run // same as -// let double = function(n) { return n*2 } +// let double = function(n) { return n * 2 } *!* -let double = n => n*2; +let double = n => n * 2; */!* alert( double(3) ); // 6 From 41dd4a724cc6a14b0749e3e9460a7b39a8aa8dc1 Mon Sep 17 00:00:00 2001 From: Shubham Gupta Date: Sat, 23 Sep 2017 17:13:36 -0700 Subject: [PATCH 045/331] Update article.md --- 2-ui/1-document/03-dom-navigation/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md index ab96e5f7..b46467c3 100644 --- a/2-ui/1-document/03-dom-navigation/article.md +++ b/2-ui/1-document/03-dom-navigation/article.md @@ -157,7 +157,7 @@ The first thing is nice. The second is tolerable, because we can use `Array.from ```warn header="DOM collections are read-only" DOM collections, and even more -- *all* navigation properties listed in this chapter are read-only. -We can't replace an child by something else assigning `childNodes[i] = ...`. +We can't replace a child by something else assigning `childNodes[i] = ...`. Changing DOM needs other methods, we'll see them in the next chapter. ``` From 0a2b9361334fe7c8064f8d64068566e6af44ed80 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 24 Sep 2017 08:58:52 +0300 Subject: [PATCH 046/331] fixes --- 1-js/03-code-quality/04-ninja-code/article.md | 4 +- 1-js/03-code-quality/06-polyfills/article.md | 2 +- 1-js/04-object-basics/01-object/article.md | 6 +- 1-js/04-object-basics/03-symbol/article.md | 57 ++++++++++--------- .../04-function-prototype/article.md | 6 +- 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md index 0b97b3ff..58bd9c2c 100644 --- a/1-js/03-code-quality/04-ninja-code/article.md +++ b/1-js/03-code-quality/04-ninja-code/article.md @@ -70,7 +70,7 @@ While choosing a name try to use the most abstract word. Like `obj`, `data`, `va ...But what to do if `data` is already taken? Try `value`, it's also universal. After all, a variable eventually gets a *value*. -- **Name the variable by its type: `str`, `num`...** +- **Name a variable by its type: `str`, `num`...** Give them a try. A young ninja may wonder -- do such names make the code worse? Actually, yes! @@ -78,7 +78,7 @@ While choosing a name try to use the most abstract word. Like `obj`, `data`, `va Indeed, the value type is easy to find out by debugging. But what's the meaning of the variable? Which string/number does it store? There's just no way to figure out without a good meditation! -- **...But what if there are no more such names?** Just add a letter: `item1, item2, elem5, data1`... +- **...But what if there are no more such names?** Just add a number: `data1, item2, elem5`... ## Attention test diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md index 37ea9f89..caf0826c 100644 --- a/1-js/03-code-quality/06-polyfills/article.md +++ b/1-js/03-code-quality/06-polyfills/article.md @@ -46,7 +46,7 @@ alert('Press the "Play" button in the upper-right corner to run'); ``` Examples that use modern JS will work only if your browser supports it. -``` +```` ```offline As you're reading the offline version, examples are not runnable. But they usually work :) diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index abb93ea4..74586d6b 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -222,7 +222,11 @@ obj.__proto__ = 5; alert(obj.__proto__); // [object Object], didn't work as intended ``` -As we see from the code, the assignment to a primitive `5` is ignored. If we want to store *arbitrary* (user-provided) keys, then such behavior can be the source of bugs and even vulnerabilities, because it's unexpected. There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. +As we see from the code, the assignment to a primitive `5` is ignored. + +That can be come a source of bugs and even vulnerabilies if we intent to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). + +There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. Also there's a way to make objects treat `__proto__` as a regular property, but first we need to know more about objects to understand it. ```` diff --git a/1-js/04-object-basics/03-symbol/article.md b/1-js/04-object-basics/03-symbol/article.md index 47fdc28b..54eb612b 100644 --- a/1-js/04-object-basics/03-symbol/article.md +++ b/1-js/04-object-basics/03-symbol/article.md @@ -9,18 +9,25 @@ Till now we've only seen strings. Now let's see the advantages that symbols can ## Symbols -"Symbol" value represents an unique identifier with a given name. +"Symbol" value represents an unique identifier. -A value of this type can be created using `Symbol(name)`: +A value of this type can be created using `Symbol()`: ```js -// id is a symbol with the name "id" +// id is a new symbol +let id = Symbol(); +``` + +We can also give symbol a description (also called a symbol name), mostly useful for debugging purposes: + +```js +// id is a symbol with the description "id" let id = Symbol("id"); ``` -Symbols are guaranteed to be unique. Even if we create many symbols with the same name, they are different values. +Symbols are guaranteed to be unique. Even if we create many symbols with the same description, they are different values. The description is just a label that doesn't affect anything. -For instance, here are two symbols with the same name -- they are not equal: +For instance, here are two symbols with the same description -- they are not equal: ```js run let id1 = Symbol("id"); @@ -56,13 +63,11 @@ alert(id.toString()); // Symbol(id), now it works That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not occasionally convert one into another. ```` - - ## "Hidden" properties Symbols allow us to create "hidden" properties of an object, that no other part of code can occasionally access or overwrite. -For instance, if we want to store an "identifier" for the object `user`, we can create a symbol with the name `id` for it: +For instance, if we want to store an "identifier" for the object `user`, we can use a symbol as a key for it: ```js run let user = { name: "John" }; @@ -72,11 +77,13 @@ user[id] = "ID Value"; alert( user[id] ); // we can access the data using the symbol as the key ``` -Now let's imagine that another script wants to have its own "id" property inside `user`, for its own purposes. That may be another JavaScript library, so the scripts are completely unaware of each other. +What's the benefit over using `Symbol("id")` over a string `"id"`? -No problem. It can create its own `Symbol("id")`. +Let's make the example a bit deeper to see that. -The script: +Imagine that another script wants to have its own "id" property inside `user`, for its own purposes. That may be another JavaScript library, so the scripts are completely unaware of each other. + +Then that script can create its own `Symbol("id")`, like this: ```js // ... @@ -87,7 +94,7 @@ user[id] = "Their id value"; There will be no conflict, because symbols are always different, even if they have the same name. -Please note that if we used a string `"id"` instead of a symbol for the same purpose, then there *would* be a conflict: +Now note that if we used a string `"id"` instead of a symbol for the same purpose, then there *would* be a conflict: ```js run let user = { name: "John" }; @@ -176,25 +183,27 @@ alert( obj[0] ); // test (same property) ## Global symbols -As we've seen, usually all symbols are different, even if they have the same name. But sometimes we want same-named symbols to be the same entities. +As we've seen, usually all symbols are different, even if they have the same names. But sometimes we want same-named symbols to be same entities. For instance, different parts of our application want to access symbol `"id"` meaning exactly the same property. To achieve that, there exists a *global symbol registry*. We can create symbols in it and access them later, and it guarantees that repeated accesses by the same name return exactly the same symbol. -In order to create or read a symbol in the registry, use `Symbol.for(name)`. +In order to create or read a symbol in the registry, use `Symbol.for(key)`. + +That call checks the global registry, and if there's a symbol described as `key`, then returns it, otherwise creates a new symbol `Symbol(key)` and stores it in the registry by the given `key`. For instance: ```js run // read from the global registry -let name = Symbol.for("name"); // if the symbol did not exist, it is created +let id = Symbol.for("id"); // if the symbol did not exist, it is created // read it again -let nameAgain = Symbol.for("name"); +let idAgain = Symbol.for("id"); // the same symbol -alert( name === nameAgain ); // true +alert( id === idAgain ); // true ``` Symbols inside the registry are called *global symbols*. If we want an application-wide symbol, accessible everywhere in the code -- that's what they are for. @@ -207,7 +216,7 @@ In JavaScript, as we can see, that's right for global symbols. ### Symbol.keyFor -For global symbols, not only `Symbol.for(name)` returns a symbol by name, but there's a reverse call: `Symbol.keyFor(sym)`, that does the reverse: returns a name by a global symbol. +For global symbols, not only `Symbol.for(key)` returns a symbol by name, but there's a reverse call: `Symbol.keyFor(sym)`, that does the reverse: returns a name by a global symbol. For instance: @@ -220,20 +229,16 @@ alert( Symbol.keyFor(sym) ); // name alert( Symbol.keyFor(sym2) ); // id ``` -The `Symbol.keyFor` internally uses the global symbol registry to look up the name for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and return `undefined`. +The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and return `undefined`. For instance: ```js run alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol -alert( Symbol.keyFor(Symbol("name2")) ); // undefined, non-global symbol +alert( Symbol.keyFor(Symbol("name2")) ); // undefined, the argument isn't a global symbol ``` -So, for global symbols the name may be indeed helpful, as we can get a symbol by id. - -And for non-global symbols the name is only used for debugging purposes, like printing out a symbol. - ## System symbols There exist many "system" symbols that JavaScript uses internally, and we can use them to fine-tune various aspects of our objects. @@ -254,9 +259,9 @@ Other symbols will also become familiar when we study the corresponding language `Symbol` is a primitive type for unique identifiers. -Symbols are created with `Symbol(name)` call. +Symbols are created with `Symbol()` call with an optional description. -Symbols are always different values, even if they have the same name. If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(name)` returns (creates if needed) a global symbol with the given name. Multiple calls of `Symbol.for` return exactly the same symbol. +Symbols are always different values, even if they have the same name. If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(key)` returns (creates if needed) a global symbol with `key` as the name. Multiple calls of `Symbol.for` return exactly the same symbol. Symbols have two main use cases: diff --git a/1-js/07-object-oriented-programming/04-function-prototype/article.md b/1-js/07-object-oriented-programming/04-function-prototype/article.md index e002014f..4abc4095 100644 --- a/1-js/07-object-oriented-programming/04-function-prototype/article.md +++ b/1-js/07-object-oriented-programming/04-function-prototype/article.md @@ -1,6 +1,6 @@ # F.prototype -In modern JavaScript we can set a prototype using `__proto__`. But it wasn't like that all the time. +In modern JavaScript we can set a prototype using `__proto__`, as described in the previous article. But it wasn't like that all the time. [cut] @@ -10,9 +10,7 @@ But in the old times, there was another (and the only) way to set it: to use a ` ## The "prototype" property -As we know already, `new F()` creates a new object. But what we didn't use yet `F.prototype` property. - -That property is used by the JavaScript itself to set `[[Prototype]]` for new objects. +As we know already, `new F()` creates a new object. In the process, its "magic" `F.prototype` property is used by the JavaScript itself to set `[[Prototype]]` for new objects. **When a new object is created with `new F()`, the object's `[[Prototype]]` is set to `F.prototype`.** From 807f0d8b2d628ba7cc1fa2f66c0c19df3e9803b6 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Mon, 25 Sep 2017 00:36:24 +0300 Subject: [PATCH 047/331] minor --- .../04-function-prototype/article.md | 6 +++-- .../article.md | 24 ++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/1-js/07-object-oriented-programming/04-function-prototype/article.md b/1-js/07-object-oriented-programming/04-function-prototype/article.md index 4abc4095..9fc9262e 100644 --- a/1-js/07-object-oriented-programming/04-function-prototype/article.md +++ b/1-js/07-object-oriented-programming/04-function-prototype/article.md @@ -10,9 +10,11 @@ But in the old times, there was another (and the only) way to set it: to use a ` ## The "prototype" property -As we know already, `new F()` creates a new object. In the process, its "magic" `F.prototype` property is used by the JavaScript itself to set `[[Prototype]]` for new objects. +As we know already, `new F()` creates a new object. -**When a new object is created with `new F()`, the object's `[[Prototype]]` is set to `F.prototype`.** +When a new object is created with `new F()`, the object's `[[Prototype]]` is set to `F.prototype`. + +In other words, if `F` has a `prototype` property with a value of the object type, then `new` operator uses it to set `[[Prototype]]` for the new object. Please note that `F.prototype` here means a regular property named `"prototype"` on `F`. It sounds something similar to the term "prototype", but here we really mean a regular property with this name. diff --git a/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md b/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md index bb4c7d6f..77d7dc31 100644 --- a/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md +++ b/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md @@ -2,11 +2,11 @@ Some regular expressions are looking simple, but can execute veeeeeery long time, and even "hang" the JavaScript engine. -Sooner or later all developers occasionally meets this behavior. +Sooner or later most developers occasionally face such behavior. -The typical situation -- a regular expression works fine for some time, and then starts to "hang" the script and make it consume 100% of CPU. +The typical situation -- a regular expression works fine sometimes, but for certain strings it "hangs" consuming 100% of CPU. -That may even be a vulnerability. For instance, if JavaScript is on the server and uses regular expressions on user data. There were many vulnerabilities of that kind even in widely distributed systems. +That may even be a vulnerability. For instance, if JavaScript is on the server, and it uses regular expressions to process user data, then such an input may cause denial of service. The author personally saw and reported such vulnerabilities even for well-known and widely used programs. So the problem is definitely worth to deal with. @@ -42,7 +42,7 @@ In the regexp language that is: `pattern:<\w+(\s*\w+=(\w+|"[^"]*")\s*)*>`: 1. `pattern:<\w+` -- is the tag start, 2. `pattern:(\s*\w+=(\w+|"[^"]*")\s*)*` -- is an arbitrary number of pairs `word=value`, where the value can be either a word `pattern:\w+` or a quoted string `pattern:"[^"]*"`. -That doesn't yet support the details of HTML grammer, for instance strings can be in 'single' quotes, but these can be added later, so that's somewhat close to real life. For now we want the regexp to be simple. +That doesn't yet support few details of HTML grammar, for instance strings in 'single' quotes, but they can be added later, so that's somewhat close to real life. For now we want the regexp to be simple. Let's try it in action: @@ -58,7 +58,7 @@ Great, it works! It found both the long tag `match:` and t Now let's see the problem. -If you run the example below, it may hang the browser (or another JavaScript engine): +If you run the example below, it may hang the browser (or whatever JavaScript engine runs): ```js run let reg = /<\w+(\s*\w+=(\w+|"[^"]*")\s*)*>/g; @@ -76,7 +76,9 @@ Some regexp engines can handle that search, but most of them don't. What's the matter? Why a simple regular expression on such a small string "hangs"? -Let's simplify the situation by removing the tag and quoted strings, we'll look only for attributes: +Let's simplify the situation by removing the tag and quoted strings. + +Here we look only for attributes: ```js run // only search for space-delimited attributes @@ -91,15 +93,15 @@ alert( str.match(reg) ); */!* ``` -The same. +The same problem persists. -Here we end the demo of the problem and start looking into what's going on. +Here we end the demo of the problem and start looking into what's going on and why it hangs. ## Backtracking To make an example even simpler, let's consider `pattern:(\d+)*$`. -In most regexp engines that search takes a very long time (careful -- can hang): +This regular expression also has the same probblem. In most regexp engines that search takes a very long time (careful -- can hang): ```js run alert( '12345678901234567890123456789123456789z'.match(/(\d+)*$/) ); @@ -107,9 +109,9 @@ alert( '12345678901234567890123456789123456789z'.match(/(\d+)*$/) ); So what's wrong with the regexp? -Actually, it looks a little bit strange. The quantifier `pattern:*` looks extraneous. If we want a number, we can use `pattern:\d+$`. +First, one may notice that the regexp is a little bit strange. The quantifier `pattern:*` looks extraneous. If we want a number, we can use `pattern:\d+$`. -Yes, the regexp is artificial, but the reason why it is slow is the same as those we saw above. So let's understand it. +Indeed, the regexp is artificial. But the reason why it is slow is the same as those we saw above. So let's understand it, and then return to the real-life examples. What happen during the search of `pattern:(\d+)*$` in the line `subject:123456789z`? From d39750fc298c1cfe1efadf76a287db4f397266a2 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Mon, 25 Sep 2017 00:36:32 +0300 Subject: [PATCH 048/331] minor --- .../15-regexp-infinite-backtracking-problem/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md b/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md index 77d7dc31..211e883a 100644 --- a/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md +++ b/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md @@ -101,7 +101,7 @@ Here we end the demo of the problem and start looking into what's going on and w To make an example even simpler, let's consider `pattern:(\d+)*$`. -This regular expression also has the same probblem. In most regexp engines that search takes a very long time (careful -- can hang): +This regular expression also has the same problem. In most regexp engines that search takes a very long time (careful -- can hang): ```js run alert( '12345678901234567890123456789123456789z'.match(/(\d+)*$/) ); From 05d39b3fc7d7f47b41cc365f78e522343f1d3c62 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 25 Sep 2017 02:46:43 +0300 Subject: [PATCH 049/331] Operator spacing and unclosed quotes --- 1-js/02-first-steps/16-javascript-specials/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/02-first-steps/16-javascript-specials/article.md b/1-js/02-first-steps/16-javascript-specials/article.md index 39e75370..5e64592d 100644 --- a/1-js/02-first-steps/16-javascript-specials/article.md +++ b/1-js/02-first-steps/16-javascript-specials/article.md @@ -216,7 +216,7 @@ switch (age) { alert("Won't work"); // the result of prompt is a string, not a number case "18": - alert("This works!""); + alert("This works!"); break; default: @@ -273,7 +273,7 @@ We covered three ways to create a function in JavaScript: - Functions may have local variables: those declared inside its body. Such variables are only visible inside the function. -- Parameters can have default values: `function sum(a=1, b=2) {...}`. +- Parameters can have default values: `function sum(a = 1, b = 2) {...}`. - Functions always return something. If there's no `return` statement, then the result is `undefined`. From 27974ecdf521a2e826f0f21224047106da453f9c Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 25 Sep 2017 03:48:17 +0300 Subject: [PATCH 050/331] Extra space & missing newline --- 1-js/03-code-quality/03-comments/article.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md index fbc49628..4f187129 100644 --- a/1-js/03-code-quality/03-comments/article.md +++ b/1-js/03-code-quality/03-comments/article.md @@ -58,8 +58,9 @@ function showPrimes(n) { function isPrime(n) { for (let i = 2; i < n; i++) { - if ( n % i == 0) return false; + if (n % i == 0) return false; } + return true; } ``` From 08cca430ca2211b71db49d288c31371189a7d039 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 25 Sep 2017 19:44:34 +0300 Subject: [PATCH 051/331] Spacing --- 1-js/02-first-steps/12-while-for/article.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/1-js/02-first-steps/12-while-for/article.md b/1-js/02-first-steps/12-while-for/article.md index 55ea6302..a8485203 100644 --- a/1-js/02-first-steps/12-while-for/article.md +++ b/1-js/02-first-steps/12-while-for/article.md @@ -21,7 +21,7 @@ while (condition) { While the `condition` is `true`, the `code` from the loop body is executed. -For instance, the loop below outputs `i` while `i<3`: +For instance, the loop below outputs `i` while `i < 3`: ```js run let i = 0; @@ -37,7 +37,7 @@ If there were no `i++` in the example above, the loop would repeat (in theory) f Any expression or a variable can be a loop condition, not just a comparison. They are evaluated and converted to boolean by `while`. -For instance, the shorter way to write `while (i!=0)` could be `while (i)`: +For instance, the shorter way to write `while (i != 0)` could be `while (i)`: ```js run let i = 3; @@ -108,8 +108,8 @@ Let's examine the `for` statement part by part: | part | | | |-------|----------|----------------------------------------------------------------------------| -| begin | `i=0` | Executes once upon entering the loop. | -| condition | `i<3`| Checked before every loop iteration, if fails the loop stops. | +| begin | `i = 0` | Executes once upon entering the loop. | +| condition | `i < 3`| Checked before every loop iteration, if fails the loop stops. | | step| `i++` | Executes after the body on each iteration, but before the condition check. | | body | `alert(i)`| Runs again and again while the condition is truthy | @@ -192,7 +192,7 @@ for (; i < 3;) { } ``` -The loop became identical to `while (i<3)`. +The loop became identical to `while (i < 3)`. We can actually remove everything, thus creating an infinite loop: @@ -324,7 +324,7 @@ The ordinary `break` after `input` would only break the inner loop. That's not s A *label* is an identifier with a colon before a loop: ```js -labelName: for(...) { +labelName: for (...) { ... } ``` @@ -369,7 +369,7 @@ For example, it is impossible to do this: ```js break label; // jumps to label? No. -label: for(...) +label: for (...) ``` The call to a `break/continue` is only possible from inside the loop, and the label must be somewhere upwards from the directive. @@ -381,7 +381,7 @@ We covered 3 types of loops: - `while` -- The condition is checked before each iteration. - `do..while` -- The condition is checked after each iteration. -- `for(;;)` -- The condition is checked before each iteration, additional settings available. +- `for (;;)` -- The condition is checked before each iteration, additional settings available. To make an "infinite" loop, usually the `while(true)` construct is used. Such a loop, just like any other, can be stopped with the `break` directive. From 4c8aedc047537a3eb325b55ea3d37371ab633376 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 25 Sep 2017 20:25:13 +0300 Subject: [PATCH 052/331] Spacing --- 1-js/02-first-steps/12-while-for/7-list-primes/task.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/02-first-steps/12-while-for/7-list-primes/task.md b/1-js/02-first-steps/12-while-for/7-list-primes/task.md index 0f92fecf..6344b9f6 100644 --- a/1-js/02-first-steps/12-while-for/7-list-primes/task.md +++ b/1-js/02-first-steps/12-while-for/7-list-primes/task.md @@ -6,12 +6,12 @@ importance: 3 An integer number greater than `1` is called a [prime](https://en.wikipedia.org/wiki/Prime_number) if it cannot be divided without a remainder by anything except `1` and itself. -In other words, `n>1` is a prime if it can't be evenly divided by anything except `1` and `n`. +In other words, `n > 1` is a prime if it can't be evenly divided by anything except `1` and `n`. For example, `5` is a prime, because it cannot be divided without a remainder by `2`, `3` and `4`. **Write the code which outputs prime numbers in the interval from `2` to `n`.** -For `n=10` the result will be `2,3,5,7`. +For `n = 10` the result will be `2,3,5,7`. P.S. The code should work for any `n`, not be hard-tuned for any fixed value. From 6b61befda3bf0f5ec2ac183ca0e64ec762cf19f3 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 25 Sep 2017 20:29:22 +0300 Subject: [PATCH 053/331] Spacing --- .../02-first-steps/12-while-for/3-which-value-for/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/02-first-steps/12-while-for/3-which-value-for/solution.md b/1-js/02-first-steps/12-while-for/3-which-value-for/solution.md index 766278fd..e2e28e75 100644 --- a/1-js/02-first-steps/12-while-for/3-which-value-for/solution.md +++ b/1-js/02-first-steps/12-while-for/3-which-value-for/solution.md @@ -8,8 +8,8 @@ for (let i = 0; i < 5; i++) alert( i ); That can be easily deducted from the algorithm of `for`: -1. Execute once `i=0` before everything (begin). -2. Check the condition `i<5` +1. Execute once `i = 0` before everything (begin). +2. Check the condition `i < 5` 3. If `true` -- execute the loop body `alert(i)`, and then `i++` The increment `i++` is separated from the condition check (2). That's just another statement. From aae4dfd17ba3c0c78950856fe1dd84d18641c62d Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 25 Sep 2017 21:19:53 +0300 Subject: [PATCH 054/331] Typo --- 1-js/04-object-basics/03-symbol/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/04-object-basics/03-symbol/article.md b/1-js/04-object-basics/03-symbol/article.md index 54eb612b..3983ae56 100644 --- a/1-js/04-object-basics/03-symbol/article.md +++ b/1-js/04-object-basics/03-symbol/article.md @@ -9,7 +9,7 @@ Till now we've only seen strings. Now let's see the advantages that symbols can ## Symbols -"Symbol" value represents an unique identifier. +"Symbol" value represents a unique identifier. A value of this type can be created using `Symbol()`: @@ -141,7 +141,7 @@ let user = { }; *!* -for(let key in user) alert(key); // name, age (no symbols) +for (let key in user) alert(key); // name, age (no symbols) */!* // the direct access by the symbol works From b91505aa03f2fad41b10203b95d0dffdcc404559 Mon Sep 17 00:00:00 2001 From: Mikkel Sandberg Date: Mon, 25 Sep 2017 11:58:19 -0700 Subject: [PATCH 055/331] 1 > 02 > 12 > skipping parts (infinite loop) There's an infinite loop on the second omit example, because i is never iterated. If you iterate inside the alert call, then that should fix it. --- 1-js/02-first-steps/12-while-for/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/12-while-for/article.md b/1-js/02-first-steps/12-while-for/article.md index 55ea6302..b043e4a6 100644 --- a/1-js/02-first-steps/12-while-for/article.md +++ b/1-js/02-first-steps/12-while-for/article.md @@ -188,7 +188,7 @@ We can also remove the `step` part: let i = 0; for (; i < 3;) { - alert( i ); + alert( i++ ); } ``` From 534c557ecd42c6d61a026d15e33a741c3b85970e Mon Sep 17 00:00:00 2001 From: Felipe Lerma Date: Mon, 25 Sep 2017 22:20:02 -0700 Subject: [PATCH 056/331] Update Solution.md - Task Typo Fix. changed "substruction" to "subtraction" in Task section of "Type Conversions." --- .../1-primitive-conversions-questions/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md b/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md index 0e1be244..a4f3fec7 100644 --- a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md +++ b/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md @@ -17,6 +17,6 @@ undefined + 1 = NaN // (4) ``` 1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied. -2. The substruction `"-"` (like most math operations) only works with numbers, it converts an empty string `""` to `0`. +2. The subtraction `"-"` (like most math operations) only works with numbers, it converts an empty string `""` to `0`. 3. `null` becomes `0` after the numeric conversion. 4. `undefined` becomes `NaN` after the numeric conversion. From 9a429354d882d56a5b7d03985e5b84bac499ff6e Mon Sep 17 00:00:00 2001 From: Felipe Lerma Date: Tue, 26 Sep 2017 22:55:47 -0700 Subject: [PATCH 057/331] update article.md for 07-operators. adding spaces: changing '2+2' to '2 + 2' --- 1-js/02-first-steps/07-operators/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/07-operators/article.md index 368e8a83..ecf90c2e 100644 --- a/1-js/02-first-steps/07-operators/article.md +++ b/1-js/02-first-steps/07-operators/article.md @@ -173,7 +173,7 @@ alert( b ); // 4 alert( c ); // 4 ``` -Chained assignments evaluate from right to left. First the rightmost expression `2+2` is evaluated then assigned to the variables on the left: `c`, `b` and `a`. At the end, all variables share a single value. +Chained assignments evaluate from right to left. First the rightmost expression `2 + 2` is evaluated then assigned to the variables on the left: `c`, `b` and `a`. At the end, all variables share a single value. ````smart header="The assignment operator `\"=\"` returns a value" An operator always returns a value. That's obvious for most of them like an addition `+` or a multiplication `*`. But the assignment operator follows that rule too. From 7890fb83b4d42090e6661d9cd6035e904de0effb Mon Sep 17 00:00:00 2001 From: Felipe Lerma Date: Tue, 26 Sep 2017 23:21:37 -0700 Subject: [PATCH 058/331] Moar spaces in 07-operators. Added moar spaces to 07-operators. --- 1-js/02-first-steps/07-operators/article.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/07-operators/article.md index ecf90c2e..df24311c 100644 --- a/1-js/02-first-steps/07-operators/article.md +++ b/1-js/02-first-steps/07-operators/article.md @@ -381,8 +381,8 @@ This notation can be shortened using operators `+=` and `*=`: ```js run let n = 2; -n += 5; // now n=7 (same as n = n + 5) -n *= 2; // now n=14 (same as n = n * 2) +n += 5; // now n = 7 (same as n = n + 5) +n *= 2; // now n = 14 (same as n = n * 2) alert( n ); // 14 ``` @@ -409,18 +409,18 @@ For example: ```js run *!* -let a = (1+2, 3+4); +let a = (1 + 2, 3 + 4); */!* -alert( a ); // 7 (the result of 3+4) +alert( a ); // 7 (the result of 3 + 4) ``` -Here, the first expression `1+2` is evaluated, and its result is thrown away, then `3+4` is evaluated and returned as the result. +Here, the first expression `1 + 2` is evaluated, and its result is thrown away, then `3 + 4` is evaluated and returned as the result. ```smart header="Comma has a very low precedence" Please note that the comma operator has very low precedence, lower than `=`, so parentheses are important in the example above. -Without them: `a=1+2,3+4` evaluates `+` first, summing the numbers into `a=3,7`, then the assignment operator `=` assigns `a=3`, and then the number after the comma `7` is not processed anyhow, so it's ignored. +Without them: `a = 1 + 2, 3 + 4` evaluates `+` first, summing the numbers into `a = 3, 7`, then the assignment operator `=` assigns `a = 3`, and then the number after the comma `7` is not processed anyhow, so it's ignored. ``` Why do we need such an operator which throws away everything except the last part? From 4245cb446755baf8ac025430fb079ed5d33aba7d Mon Sep 17 00:00:00 2001 From: kosoado Date: Wed, 27 Sep 2017 06:44:57 -0500 Subject: [PATCH 059/331] Fix single quotes mismatch. --- 5-regular-expressions/12-regexp-anchors/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5-regular-expressions/12-regexp-anchors/article.md b/5-regular-expressions/12-regexp-anchors/article.md index b4ae67cf..e1873a49 100644 --- a/5-regular-expressions/12-regexp-anchors/article.md +++ b/5-regular-expressions/12-regexp-anchors/article.md @@ -9,7 +9,7 @@ The caret `pattern:^` matches at the beginning of the text, and the dollar `patt For instance, let's test if the text starts with `Mary`: ```js run -let str1 = 'Mary had a little lamb, it's fleece was white as snow'; +let str1 = "Mary had a little lamb, it's fleece was white as snow"; let str2 = 'Everywhere Mary went, the lamp was sure to go'; alert( /^Mary/.test(str1) ); // true From 163e61a208ede176bf98dd80f041d7b16ca25fb6 Mon Sep 17 00:00:00 2001 From: kosoado Date: Wed, 27 Sep 2017 06:48:12 -0500 Subject: [PATCH 060/331] Fix typo --- .../15-regexp-infinite-backtracking-problem/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md b/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md index 211e883a..5dd4c446 100644 --- a/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md +++ b/5-regular-expressions/15-regexp-infinite-backtracking-problem/article.md @@ -121,7 +121,7 @@ What happen during the search of `pattern:(\d+)*$` in the line `subject:12345678 \d+....... (123456789)z ``` -2. Then it tries to apply the start around the parentheses `pattern:(\d+)*`, but there are no more digits, so it the star doesn't give anything. +2. Then it tries to apply the star around the parentheses `pattern:(\d+)*`, but there are no more digits, so it the star doesn't give anything. Then the pattern has the string end anchor `pattern:$`, and in the text we have `subject:z`. From 899e3e17de2edb76733e827a7207075476b5cd26 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Thu, 28 Sep 2017 01:14:52 +0300 Subject: [PATCH 061/331] fixes --- 6-async/03-promise-chaining/article.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/6-async/03-promise-chaining/article.md b/6-async/03-promise-chaining/article.md index 41acc387..e59365fc 100644 --- a/6-async/03-promise-chaining/article.md +++ b/6-async/03-promise-chaining/article.md @@ -1,7 +1,7 @@ # Promises chaining -Let's return to the problem mentioned in the chapter : +Let's return to the problem mentioned in the chapter . - We have a sequence of asynchronous tasks to be done one after another. For instance, loading scripts. - How to code it well? @@ -617,12 +617,13 @@ What happens when an error is not handled? For instance, after the rethrow as in ```js untrusted run refresh new Promise(function() { noSuchFunction(); // Error here (no such function) -}); +}); // no .catch attached ``` Or here: ```js untrusted run refresh +// a chain of promises without .catch at the end new Promise(function() { throw new Error("Whoops!"); }).then(function() { @@ -634,9 +635,9 @@ new Promise(function() { }); ``` -In theory, nothing should happen. In case of an error happens, the promise state becomes "rejected", and the execution should jump to the closest rejection handler. But there is no such handler in the examples above. So the error gets "stuck". +In case of an error, the promise state becomes "rejected", and the execution should jump to the closest rejection handler. But there is no such handler in the examples above. So the error gets "stuck". -In practice, that means that the code is bad. Indeed, how come that there's no error handling? +In practice, that's usually because of the bad code. Indeed, how come that there's no error handling? Most JavaScript engines track such situations and generate a global error in that case. We can see it in the console. From 4858aaa062c2629a1b08c5603a885c181e1831e1 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 28 Sep 2017 01:18:05 +0300 Subject: [PATCH 062/331] Typo --- 1-js/04-object-basics/05-object-toprimitive/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/04-object-basics/05-object-toprimitive/article.md b/1-js/04-object-basics/05-object-toprimitive/article.md index 943fd022..2bb32700 100644 --- a/1-js/04-object-basics/05-object-toprimitive/article.md +++ b/1-js/04-object-basics/05-object-toprimitive/article.md @@ -213,7 +213,7 @@ For instance: ```smart header="Historical notes" For historical reasons, methods `toString` or `valueOf` *should* return a primitive: if any of them returns an object, then there's no error, but that object is ignored (like if the method didn't exist). -In contrast, `Symbol.toPrimitive` *must* return an primitive, otherwise there will be an error. +In contrast, `Symbol.toPrimitive` *must* return a primitive, otherwise, there will be an error. ``` ## Summary From 14a926c7a33a259b10ef17a399c3612a10511bda Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 28 Sep 2017 07:15:40 +0300 Subject: [PATCH 063/331] Typos & spacing --- 1-js/04-object-basics/01-object/article.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index 74586d6b..978b842a 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -9,7 +9,7 @@ In contrast, objects are used to store keyed collections of various data and mor An object can be created with figure brackets `{…}` with an optional list of *properties*. A property is a "key: value" pair, where `key` is a string (also called a "property name"), and `value` can be anything. -We can imagine an object as a cabinet with signed files. Every piece of data is stored in it's file by the key. It's easy to find a file by it's name or add/remove a file. +We can imagine an object as a cabinet with signed files. Every piece of data is stored in its file by the key. It's easy to find a file by its name or add/remove a file. ![](object.png) @@ -224,7 +224,7 @@ alert(obj.__proto__); // [object Object], didn't work as intended As we see from the code, the assignment to a primitive `5` is ignored. -That can be come a source of bugs and even vulnerabilies if we intent to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). +That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. In that case, the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. Also there's a way to make objects treat `__proto__` as a regular property, but first we need to know more about objects to understand it. ```` @@ -335,12 +335,12 @@ Situations like this happen very rarely, because `undefined` is usually not assi ## The "for..in" loop -To walk over all keys of an object, there exists a special form of the loop: `for..in`. This is a completely different thing from the `for(;;)` construct that we studied before. +To walk over all keys of an object, there exists a special form of the loop: `for..in`. This is a completely different thing from the `for (;;)` construct that we studied before. The syntax: ```js -for(key in object) { +for (key in object) { // executes the body for each key among object properties } ``` @@ -354,7 +354,7 @@ let user = { isAdmin: true }; -for(let key in user) { +for (let key in user) { // keys alert( key ); // name, age, isAdmin // values for the keys @@ -364,7 +364,7 @@ for(let key in user) { Note that all "for" constructs allow us to declare the looping variable inside the loop, like `let key` here. -Also, we could use another variable name here instead of `key`. For instance, `"for(let prop in obj)"` is also widely used. +Also, we could use another variable name here instead of `key`. For instance, `"for (let prop in obj)"` is also widely used. ### Ordered like an object @@ -385,7 +385,7 @@ let codes = { }; *!* -for(let code in codes) { +for (let code in codes) { alert(code); // 1, 41, 44, 49 } */!* @@ -443,7 +443,7 @@ let codes = { "+1": "USA" }; -for(let code in codes) { +for (let code in codes) { alert( +code ); // 49, 41, 44, 1 } ``` @@ -700,7 +700,7 @@ user.sizes.width++; // change a property from one place alert(clone.sizes.width); // 51, see the result from the other one ``` -To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate it's structure as well. That is called a "deep cloning". +To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning". There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://w3c.github.io/html/infrastructure.html#internal-structured-cloning-algorithm). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). @@ -721,7 +721,7 @@ To access a property, we can use: Additional operators: - To delete a property: `delete obj.prop`. - To check if a property with the given key exists: `"key" in obj`. -- To iterate over an object: `for(let key in obj)` loop. +- To iterate over an object: `for (let key in obj)` loop. Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object. All operations via copied references (like adding/removing properties) are performed on the same single object. From 0aaa498d2cf76a411c790f17551bb3c5ac3f5ad0 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 28 Sep 2017 07:31:09 +0300 Subject: [PATCH 064/331] Spacing --- 1-js/04-object-basics/01-object/3-is-empty/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/04-object-basics/01-object/3-is-empty/solution.md b/1-js/04-object-basics/01-object/3-is-empty/solution.md index cd50543e..b3f40e3d 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/solution.md +++ b/1-js/04-object-basics/01-object/3-is-empty/solution.md @@ -2,7 +2,7 @@ Just loop over the object and `return false` immediately if there's at least one ```js function isEmpty(obj) { - for(let key in obj) { + for (let key in obj) { return false; } return true; From cb37ad9291999f35d26b6866b71a5da696de699c Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 28 Sep 2017 07:36:07 +0300 Subject: [PATCH 065/331] Spacing --- 1-js/04-object-basics/01-object/5-sum-object/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/04-object-basics/01-object/5-sum-object/solution.md b/1-js/04-object-basics/01-object/5-sum-object/solution.md index eb5b176a..63df8784 100644 --- a/1-js/04-object-basics/01-object/5-sum-object/solution.md +++ b/1-js/04-object-basics/01-object/5-sum-object/solution.md @@ -4,10 +4,10 @@ let salaries = { John: 100, Ann: 160, Pete: 130 -} +}; let sum = 0; -for(let key in salaries) { +for (let key in salaries) { sum += salaries[key]; } From 560eb0e9b40b2dedc718ea376a1c8077f3654936 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 28 Sep 2017 07:47:39 +0300 Subject: [PATCH 066/331] Typo --- 1-js/05-data-types/01-primitives-methods/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c583eced..e8221907 100644 --- a/1-js/05-data-types/01-primitives-methods/article.md +++ b/1-js/05-data-types/01-primitives-methods/article.md @@ -70,7 +70,7 @@ So primitives can provide methods, but they still remain lightweight. The JavaScript engine highly optimizes this process. It may even skip the creation of the extra object at all. But it must still adhere to the specification and behave as if it creates one. -A number has methods of it's own, for instance, [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) rounds the number to the given precision: +A number has methods of its own, for instance, [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) rounds the number to the given precision: ```js run let n = 1.23456; From 8407e7726e5c0e979f10d87ca84ab68a252949d8 Mon Sep 17 00:00:00 2001 From: Luis Gustavo Nardin Date: Thu, 28 Sep 2017 15:17:28 +0200 Subject: [PATCH 067/331] Update article.md --- 1-js/02-first-steps/05-types/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md index 3e2de60a..32252213 100644 --- a/1-js/02-first-steps/05-types/article.md +++ b/1-js/02-first-steps/05-types/article.md @@ -191,7 +191,7 @@ It supports two forms of syntax: 1. As an operator: `typeof x`. 2. Function style: `typeof(x)`. -In other words, it works both with the brackets or without them. The result is the same. +In other words, it works both with parentheses or without them. The result is the same. The call to `typeof x` returns a string with the type name: From 2d8ae03fb019baa27cb6c2bccf923df561d273b4 Mon Sep 17 00:00:00 2001 From: Amanda Bozigian Date: Thu, 28 Sep 2017 14:09:27 -0700 Subject: [PATCH 068/331] Update article.md Ln 53, "then" --> "than" Changed: For instance, a `focus` event does not bubble. There are other examples too, we'll meet them. But still it's an exception, rather then a rule, most events do bubble. To: For instance, a `focus` event does not bubble. There are other examples too, we'll meet them. But still it's an exception, rather than a rule, most events do bubble. --- 2-ui/2-events/02-bubbling-and-capturing/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index 05da72fc..e1c287cc 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -50,7 +50,7 @@ The process is called "bubbling", because events "bubble" from the inner element ```warn header="*Almost* all events bubble." The key word in this phrase is "almost". -For instance, a `focus` event does not bubble. There are other examples too, we'll meet them. But still it's an exception, rather then a rule, most events do bubble. +For instance, a `focus` event does not bubble. There are other examples too, we'll meet them. But still it's an exception, rather than a rule, most events do bubble. ``` ## event.target From 60609fbd74f976a2f6144cadc9b80739f849d9c9 Mon Sep 17 00:00:00 2001 From: Tovieye Moses Ozi Date: Thu, 28 Sep 2017 22:42:41 +0100 Subject: [PATCH 069/331] Update article.md --- .../09-destructuring-assignment/article.md | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/1-js/05-data-types/09-destructuring-assignment/article.md b/1-js/05-data-types/09-destructuring-assignment/article.md index df553aeb..55df9399 100644 --- a/1-js/05-data-types/09-destructuring-assignment/article.md +++ b/1-js/05-data-types/09-destructuring-assignment/article.md @@ -2,9 +2,9 @@ The two most used data structures in JavaScript are `Object` and `Array`. -Objects allow to pack many pieces of information into a single entity and arrays allow to store ordered collections. So we can make an object or an array and handle it as a single thing, maybe pass to a function call. +Objects allow us to pack many pieces of information into a single entity and arrays allow us to store ordered collections. So we can make an object or an array and handle it as a single entity, or maybe pass it to a function call. -*Destructuring assignment* is a special syntax that allows to "unpack" arrays or objects into a bunch of variables, as sometimes they are more convenient. Destructuring also works great with complex functions that have a lot of parameters, default values, and soon we'll see how these are handled too. +*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes they are more convenient. Destructuring also works great with complex functions that have a lot of parameters, default values, and soon we'll see how these are handled too. [cut] @@ -34,9 +34,9 @@ let [firstName, surname] = "Ilya Kantor".split(' '); ``` ````smart header="\"Destructuring\" does not mean \"destructive\"" -That's called "destructuring assignment", because it "destructurizes" by copying items into variables. But the array itself is not modified. +It's called "destructuring assignment", because it "destructurizes" by copying items into variables. But the array itself is not modified. -That's just a shorter way to write: +It's just a shorter way to write: ```js // let [firstName, surname] = arr; let firstName = arr[0]; @@ -56,12 +56,12 @@ let [, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; alert( title ); // Consul ``` -In the code above, the first and second elements of the array are skipped, the third one is assigned to `title`, and the rest is also skipped. +In the code above, although the first and second elements of the array are skipped, the third one is assigned to `title`, and the rest are also skipped. ```` ````smart header="Works with any iterable on the right-side" -...Actually, we can use it with any iterable, not only an array: +...Actually, we can use it with any iterable, not only arrays: ```js let [a, b, c] = "abc"; // ["a", "b", "c"] @@ -87,7 +87,7 @@ alert(user.name); // Ilya ````smart header="Looping with .entries()" -In the previous chapter we saw [Object.entries(obj)](mdn:js/Object/entries) method. +In the previous chapter we saw the [Object.entries(obj)](mdn:js/Object/entries) method. We can use it with destructuring to loop over keys-and-values of an object: @@ -121,7 +121,7 @@ for(let [key, value] of user.entries()) { ```` ### The rest '...' -If we want not just to get first values, but also to gather all that follows -- we can add one more parameter that gets "the rest" using the three dots `"..."`: +If we want not just to get first values, but also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`: ```js run let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*]; @@ -136,11 +136,11 @@ alert(rest.length); // 2 */!* ``` -The value of `rest` is the array of the remaining array elements. We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes the last. +The value of `rest` is the array of the remaining array elements. We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignmemnt. ### Default values -If there are fewer values in the array than variables in the assignment -- there will be no error, absent values are considered undefined: +If there are fewer values in the array than variables in the assignment, there will be no error. Absent values are considered undefined: ```js run *!* @@ -164,7 +164,7 @@ alert(surname); // Anonymous (default used) Default values can be more complex expressions or even function calls. They are evaluated only if the value is not provided. -For instance, here we use `prompt` function for two defaults. But it will only run only for the missing one: +For instance, here we use the `prompt` function for two defaults. But it will run only for the missing one: ```js run // runs only prompt for surname @@ -186,7 +186,7 @@ The basic syntax is: let {var1, var2} = {var1:…, var2…} ``` -We have an existing object at the right side, that we want to split into variables. To the left side contains a "pattern" for corresponding properties. In the simple case that's a list of variable names in `{...}`. +We have an existing object at the right side, that we want to split into variables. The left side contains a "pattern" for corresponding properties. In the simple case, that's a list of variable names in `{...}`. For instance: @@ -206,7 +206,7 @@ alert(width); // 100 alert(height); // 200 ``` -Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. The order does not matter, that works too: +Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. The order does not matter. This works too: ```js // changed the order of properties in let {...} @@ -258,7 +258,7 @@ alert(height); // 200 Just like with arrays or function parameters, default values can be any expressions or even function calls. They will be evaluated if the value is not provided. -The code below asks for width, but not about the title. +The code below asks for width, but not the title. ```js run let options = { @@ -391,7 +391,7 @@ Finally, we have `width`, `height`, `item1`, `item2` and `title` from the defaul That often happens with destructuring assignments. We have a complex object with many properties and want to extract only what we need. -Even like this: +Even here it happens: ```js // take size as a whole into a variable, ignore the rest let { size } = options; @@ -409,7 +409,7 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) { } ``` -The real-life problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default. +In real-life the problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default. Like this? @@ -498,7 +498,7 @@ In the code above, the whole arguments object is `{}` by default, so there's alw ## Summary -- Destructuring assignment allows to instantly map an object or array into many variables. +- Destructuring assignment allows for instantly mapping an object or array onto many variables. - The object syntax: ```js let {prop : varName = default, ...} = object From fd1eaf40b6cf2dca27fe3a19a20ade5690157235 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 29 Sep 2017 04:39:12 +0300 Subject: [PATCH 070/331] Typo & spacing --- 1-js/05-data-types/02-number/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md index 0a9feb1c..16e4275e 100644 --- a/1-js/05-data-types/02-number/article.md +++ b/1-js/05-data-types/02-number/article.md @@ -249,10 +249,10 @@ Can we work around the problem? Sure, there're a number of ways: 2. We can temporarily turn numbers into integers for the maths and then revert it back. It works like this: ```js run - alert( (0.1*10 + 0.2*10) / 10 ); // 0.3 + alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3 ``` - This works because when we do `0.1*10 = 1` and `0.2 * 10 = 2` then both numbers become integers, and there's no precision loss. + This works because when we do `0.1 * 10 = 1` and `0.2 * 10 = 2` then both numbers become integers, and there's no precision loss. 3. If we were dealing with a shop, then the most radical solution would be to store all prices in cents and use no fractions at all. But what if we apply a discount of 30%? In practice, totally evading fractions is rarely feasible, so the solutions above help avoid this pitfall. @@ -270,7 +270,7 @@ JavaScript doesn't trigger an error in such events. It does its best to fit the ```` ```smart header="Two zeroes" -Another funny consequence of the internal representation of numbers is the existance of two zeroes: `0` and `-0`. +Another funny consequence of the internal representation of numbers is the existence of two zeroes: `0` and `-0`. That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero. From 8c6f614dc4f5db82495b01b4944f37ab8f58842d Mon Sep 17 00:00:00 2001 From: Valerii Iatsko Date: Sun, 1 Oct 2017 09:34:43 +0200 Subject: [PATCH 071/331] Fixed spy-decorator assignment test Hi! We should be checking here original function not spy to ensure that we are wrapping transparently. The test wasn't working and probably that was just a "typo" to begin with. This makes it work properly. --- .../01-spy-decorator/_js.view/test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/_js.view/test.js index 7e84f3c9..b9347c90 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/_js.view/test.js +++ b/1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/_js.view/test.js @@ -24,7 +24,7 @@ describe("spy", function() { let wrappedSum = spy(sum); assert.equal(wrappedSum(1, 2), 3); - assert(spy.calledWith(1, 2)); + assert(sum.calledWith(1, 2)); }); @@ -37,8 +37,8 @@ describe("spy", function() { calc.wrappedSum = spy(calc.sum); assert.equal(calculator.wrappedSum(1, 2), 3); - assert(spy.calledWith(1, 2)); - assert(spy.calledOn(calculator)); + assert(calc.sum.calledWith(1, 2)); + assert(calc.sum.calledOn(calculator)); }); -}); \ No newline at end of file +}); From ed0e64b838e4b912277a2d975f0366c4455540b8 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Mon, 2 Oct 2017 12:06:27 +0300 Subject: [PATCH 072/331] minor --- 1-js/04-object-basics/01-object/article.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index 74586d6b..31e164d9 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -224,9 +224,12 @@ alert(obj.__proto__); // [object Object], didn't work as intended As we see from the code, the assignment to a primitive `5` is ignored. -That can be come a source of bugs and even vulnerabilies if we intent to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). +That can become a source of bugs and even vulnerabilies if we intent to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. -There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. Also there's a way to make objects treat `__proto__` as a regular property, but first we need to know more about objects to understand it. +In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). + +There exist a way to make objects treat `__proto__` as a regular property, we'll cover it later, but first we need to know more about objects to understand it. +There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. Also ```` From 2be0ffd289a88d2b35d3e56d06318e1a17348d2a Mon Sep 17 00:00:00 2001 From: Georgy Date: Mon, 2 Oct 2017 14:29:44 -0400 Subject: [PATCH 073/331] Fix typos, 07-map-set-weakmap-weakset --- 1-js/05-data-types/07-map-set-weakmap-weakset/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/05-data-types/07-map-set-weakmap-weakset/article.md b/1-js/05-data-types/07-map-set-weakmap-weakset/article.md index 40ff18b5..0769f57d 100644 --- a/1-js/05-data-types/07-map-set-weakmap-weakset/article.md +++ b/1-js/05-data-types/07-map-set-weakmap-weakset/article.md @@ -16,7 +16,7 @@ The main methods are: - `new Map()` -- creates the map. - `map.set(key, value)` -- stores the value by the key. -- `map.get(key)` -- returns the value by the key. +- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map. - `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise. - `map.delete(key)` -- removes the value by the key. - `map.clear()` -- clears the map @@ -148,7 +148,7 @@ for(let amount of recipeMap.values()) { // iterate over [key, value] entries for(let entry of recipeMap) { // the same as of recipeMap.entries() - alert(entry); // cucumber,50 (and so on) + alert(entry); // cucumber,500 (and so on) } ``` @@ -160,7 +160,7 @@ Besides that, `Map` has a built-in `forEach` method, similar to `Array`: ```js recipeMap.forEach( (value, key, map) => { - alert(`${key}: ${value}`); // cucumber: 50 etc + alert(`${key}: ${value}`); // cucumber: 500 etc }); ``` From 4f584b0515cc4ebcd9a9317a7a4d1d91dfc35b28 Mon Sep 17 00:00:00 2001 From: Georgy Date: Mon, 2 Oct 2017 14:47:40 -0400 Subject: [PATCH 074/331] Fix typo, 08-keys-values-entries --- 1-js/05-data-types/08-keys-values-entries/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md index 083ed9a3..a33f17e5 100644 --- a/1-js/05-data-types/08-keys-values-entries/article.md +++ b/1-js/05-data-types/08-keys-values-entries/article.md @@ -32,7 +32,7 @@ For plain objects, the following methods are available: The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`. -Why so? There main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `order` that implements its own `order.values()` method. And we still can call `Object.values(order)` on it. +Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `order` that implements its own `order.values()` method. And we still can call `Object.values(order)` on it. The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons. From f51afac4acbc97571149a1ab892f0f82fcf83bcc Mon Sep 17 00:00:00 2001 From: RobotWizard Date: Thu, 5 Oct 2017 09:56:41 +0530 Subject: [PATCH 075/331] fixed typo on line 44 minor fix. --- 2-ui/1-document/02-dom-nodes/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/1-document/02-dom-nodes/article.md b/2-ui/1-document/02-dom-nodes/article.md index 635986d1..db47859e 100644 --- a/2-ui/1-document/02-dom-nodes/article.md +++ b/2-ui/1-document/02-dom-nodes/article.md @@ -41,7 +41,7 @@ drawHtmlTree(node1, 'div.domtree', 690, 320); ```online -On the picture above element nodes you can click on element nodes. Their children will open/collapse. +On the picture above, you can click on element nodes and their children will open/collapse. ``` Tags are called *element nodes* (or just elements). Nested tags become children of the enclosing ones. As a result we have a tree of elements: `` is at the root, then `` and `` are its children etc. From 6eccd9dbbbb0e5800611b23c5b20d6fbcc3977d9 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 5 Oct 2017 19:00:20 +0200 Subject: [PATCH 076/331] Update article.md --- 1-js/06-advanced-functions/10-bind/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 87637929..19718199 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -72,7 +72,7 @@ setTimeout(() => user.sayHi(), 1000); // Hello, John! Looks fine, but a slight vulnerability appears in our code structure. -What if before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, the it will call the wrong object! +What if before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, it will call the wrong object! ```js run From 70d1d874f6c253d13c9320f9c16481a7a5874f36 Mon Sep 17 00:00:00 2001 From: Amid Dadgar Date: Fri, 6 Oct 2017 17:05:26 +0330 Subject: [PATCH 077/331] Fix for replacing the middle item in an Array the provided code `styles[(styles.length - 1) / 2] = "Classics";` will replace the last item instead of the middle one. in order to fix that we need to change code like this : `styles[Math.floor((styles.length - 1) / 2)] = "Classics";` --- 1-js/05-data-types/04-array/2-create-array/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/04-array/2-create-array/solution.md b/1-js/05-data-types/04-array/2-create-array/solution.md index 24351434..eec9055e 100644 --- a/1-js/05-data-types/04-array/2-create-array/solution.md +++ b/1-js/05-data-types/04-array/2-create-array/solution.md @@ -3,7 +3,7 @@ ```js run let styles = ["Jazz", "Blues"]; styles.push("Rock-n-Roll"); -styles[(styles.length + 1) / 2] = "Classics"; +styles[Math.floor((styles.length - 1) / 2)] = "Classics"; alert( styles.shift() ); styles.unshift("Rap", "Reggie"); ``` From 34c0a5a7045fa28bfcb4f06327b5a18b6272501c Mon Sep 17 00:00:00 2001 From: Johann Miller Date: Fri, 6 Oct 2017 16:01:26 -0400 Subject: [PATCH 078/331] Fix typo: 'pop to end' in Arrays:Stacks --- 1-js/05-data-types/04-array/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index 781699f7..8246c9dd 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -113,7 +113,7 @@ There's another use case for arrays -- the data structure named [stack](https:// It supports two operations: - `push` adds an element to the end. -- `pop` takes an element to the end. +- `pop` takes an element from the end. So new elements are added or taken always from the "end". From 3c08cc446b0e28bd1c671c8aaa95290d92846a22 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 7 Oct 2017 17:50:22 +0300 Subject: [PATCH 079/331] minor --- 2-ui/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/index.md b/2-ui/index.md index 5c4e1484..d94378cf 100644 --- a/2-ui/index.md +++ b/2-ui/index.md @@ -1,3 +1,3 @@ -# Browser: Document, DOM, Interfaces +# Browser: Document, Events, Interfaces Learning how to manage the browser page: add elements, manipulate their size and position, dynamically create interfaces and interact with the visitor. From de725bd171bf53bf259a99840a1e6edc4e3b942c Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Wed, 11 Oct 2017 14:18:27 +0300 Subject: [PATCH 080/331] up --- 1-js/05-data-types/03-string/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index dfa2fc25..8f8a40c5 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -49,7 +49,7 @@ let guestList = "Guests: // Error: Unexpected token ILLEGAL Single and double quotes come from ancient times of language creation when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile. -Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. You can read more about it in the [docs](mdn:JavaScript/Reference/Template_literals#Tagged_template_literals). This is called "tagged templates". This feature makes it easier to wrap strings into custom templating or other functionality, but it is rarely used. +Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. You can read more about it in the [docs](mdn:/JavaScript/Reference/Template_literals#Tagged_template_literals). This is called "tagged templates". This feature makes it easier to wrap strings into custom templating or other functionality, but it is rarely used. ## Special characters From 71fec328c12b481b4578a56c50f792ab8fd3b4c2 Mon Sep 17 00:00:00 2001 From: Zaramont Date: Wed, 11 Oct 2017 14:43:17 +0300 Subject: [PATCH 081/331] Spelling mistake in word "behavior" Spelling mistake in word "behavior" --- .../14-function-basics/1-if-else-required/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/14-function-basics/1-if-else-required/task.md b/1-js/02-first-steps/14-function-basics/1-if-else-required/task.md index 743ba78a..4f69a5c8 100644 --- a/1-js/02-first-steps/14-function-basics/1-if-else-required/task.md +++ b/1-js/02-first-steps/14-function-basics/1-if-else-required/task.md @@ -35,4 +35,4 @@ function checkAge(age) { } ``` -Is there any difference in the bahavior of these two variants? +Is there any difference in the behavior of these two variants? From bfb9ca52dfd4615833c2532cf9d99927849cfb10 Mon Sep 17 00:00:00 2001 From: Dallin parker Date: Wed, 11 Oct 2017 12:54:45 -0400 Subject: [PATCH 082/331] Update article.md I believe you're referring to a "novice" user --- 1-js/07-object-oriented-programming/09-class/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/07-object-oriented-programming/09-class/article.md b/1-js/07-object-oriented-programming/09-class/article.md index 717376e8..549a40e1 100644 --- a/1-js/07-object-oriented-programming/09-class/article.md +++ b/1-js/07-object-oriented-programming/09-class/article.md @@ -43,7 +43,7 @@ let user = new User("John"); user.sayHi(); ``` -It's easy to see that the two examples are alike. Just please note that methods in a class do not have a comma between them. Notice developers sometimes forget it and put a comma between class methods, and things don't work. That's not a literal object, but a class syntax. +It's easy to see that the two examples are alike. Just please note that methods in a class do not have a comma between them. Novice developers sometimes forget it and put a comma between class methods, and things don't work. That's not a literal object, but a class syntax. So, what exactly does `class` do? We may think that it defines a new language-level entity, but that would be wrong. From 50e6a1571d8801750507e7127814f93ea8a2eb55 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 14 Oct 2017 01:19:47 +0300 Subject: [PATCH 083/331] Typos --- 1-js/05-data-types/03-string/article.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md index 8f8a40c5..b74399a9 100644 --- a/1-js/05-data-types/03-string/article.md +++ b/1-js/05-data-types/03-string/article.md @@ -19,7 +19,7 @@ let double = "double-quoted"; let backticks = `backticks`; ``` -Single and double quotes are essentially the same. Backticks however allow us to embed any expression into the string, including function calls: +Single and double quotes are essentially the same. Backticks, however, allow us to embed any expression into the string, including function calls: ```js run function sum(a, b) { @@ -89,7 +89,7 @@ Examples with unicode: ```js run alert( "\u00A9" ); // © alert( "\u{20331}" ); // 佫, a rare chinese hieroglyph (long unicode) -alert( "\u{1F60D}"); // 😍, a smiling face symbol (another long unicode) +alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long unicode) ``` All special characters start with a backslash character `\`. It is also called an "escape character". @@ -166,7 +166,7 @@ alert( str.charAt(1000) ); // '' (an empty string) We can also iterate over characters using `for..of`: ```js run -for(let char of "Hello") { +for (let char of "Hello") { alert(char); // H,e,l,l,o (char becomes "H", then "e", then "l" etc) } ``` @@ -379,8 +379,8 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and ```js run let str = "stringify"; - alert( str.slice(0,5) ); // 'strin', the substring from 0 to 5 (not including 5) - alert( str.slice(0,1) ); // 's', from 0 to 1, but not including 1, so only character at 0 + alert( str.slice(0, 5) ); // 'strin', the substring from 0 to 5 (not including 5) + alert( str.slice(0, 1) ); // 's', from 0 to 1, but not including 1, so only character at 0 ``` If there is no second argument, then `slice` goes till the end of the string: @@ -548,7 +548,7 @@ For instance: alert( 'Österreich'.localeCompare('Zealand') ); // -1 ``` -This method actually has two additional arguments specified in [the documentation](mdn:js/String/localeCompare), which allow it to specify the language (by default taken from the environment) and setup additional rules like case sensivity or should `"a"` and `"á"` be treated as the same etc. +This method actually has two additional arguments specified in [the documentation](mdn:js/String/localeCompare), which allows it to specify the language (by default taken from the environment) and setup additional rules like case sensitivity or should `"a"` and `"á"` be treated as the same etc. ## Internals, Unicode From 089af82ee25eea9ed3d440b822198819cb4b90ba Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 14 Oct 2017 11:31:13 +0300 Subject: [PATCH 084/331] Update article.md --- 1-js/05-data-types/04-array/article.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md index 8246c9dd..825cfbed 100644 --- a/1-js/05-data-types/04-array/article.md +++ b/1-js/05-data-types/04-array/article.md @@ -297,7 +297,7 @@ But for arrays there is another form of loop, `for..of`: let fruits = ["Apple", "Orange", "Plum"]; // iterates over array elements -for(let fruit of fruits) { +for (let fruit of fruits) { alert( fruit ); } ``` @@ -356,7 +356,7 @@ arr.length = 5; // return length back alert( arr[3] ); // undefined: the values do not return ``` -So, the simplest way to clear the array is: `arr.length=0`. +So, the simplest way to clear the array is: `arr.length = 0;`. ## new Array() [#new-array] @@ -385,9 +385,9 @@ In the code above, `new Array(number)` has all elements `undefined`. To evade such surprises, we usually use square brackets, unless we really know what we're doing. -## Multidimentional arrays +## Multidimensional arrays -Arrays can have items that are also arrays. We can use it for multidimentional arrays, to store matrices: +Arrays can have items that are also arrays. We can use it for multidimensional arrays, to store matrices: ```js run let matrix = [ @@ -458,9 +458,9 @@ We can use an array as a deque with the following operations: - `unshift(...items)` adds items to the beginning. To loop over the elements of the array: - - `for(let i=0; i. From 3322f52122a8ba28bac43acc318347df6af74405 Mon Sep 17 00:00:00 2001 From: lilifan Date: Sat, 14 Oct 2017 23:23:14 +0800 Subject: [PATCH 085/331] correct type mistake correct type mistake --- 1-js/06-advanced-functions/08-settimeout-setinterval/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md index ec645913..358d497a 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md @@ -325,7 +325,7 @@ Then the next call is scheduled in `(*)` if we're not done yet. Pauses between `count` executions provide just enough "breath" for the JavaScript engine to do something else, to react on other user actions. -The notable thing is that both variants: with and without splitting the job by `setInterval` -- are comparable in speed. There's no much difference in the overall counting time. +The notable thing is that both variants: with and without splitting the job by `setTimeout` -- are comparable in speed. There's no much difference in the overall counting time. To make them closer let's make an improvement. From e171db026f508721d0e499bed49d7b4788314fde Mon Sep 17 00:00:00 2001 From: lilifan Date: Sat, 14 Oct 2017 23:45:03 +0800 Subject: [PATCH 086/331] correct type mistake Sorry to bother , but it seems that in such situations , the minimal delay is increased instead of decreased ? --- 1-js/06-advanced-functions/08-settimeout-setinterval/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md index ec645913..304651b7 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md @@ -461,4 +461,4 @@ For example, the in-browser timer may slow down for a lot of reasons: - The browser tab is in the background mode. - The laptop is on battery. -All that may decrease the minimal timer resolution (the minimal delay) to 300ms or even 1000ms depending on the browser and settings. +All that may increase the minimal timer resolution (the minimal delay) to 300ms or even 1000ms depending on the browser and settings. From 217eb0e5fa3181e79aa06822e3a444052402ba63 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 14 Oct 2017 23:52:37 +0300 Subject: [PATCH 087/331] minor --- 2-ui/2-events/02-bubbling-and-capturing/article.md | 2 +- .../bubble-target.view/script.js | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index e1c287cc..bc5d70dc 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -5,7 +5,7 @@ Let's start with an example. This handler is assigned to `
`, but also runs if you click any nested tag like `` or ``: ```html autorun height=60 -
+
If you click on EM, the handler on DIV runs.
``` diff --git a/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/script.js b/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/script.js index d3959a68..b1353712 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/script.js +++ b/2-ui/2-events/02-bubbling-and-capturing/bubble-target.view/script.js @@ -2,7 +2,9 @@ form.onclick = function(event) { event.target.style.backgroundColor = 'yellow'; - alert("target = " + event.target.tagName + ", this=" + this.tagName); - - event.target.style.backgroundColor = ''; + // chrome needs some time to paint yellow + setTimeout(() => { + alert("target = " + event.target.tagName + ", this=" + this.tagName); + event.target.style.backgroundColor = '' + }, 0); }; From 4d60cd525f6bcc283d16b808183d8ab2b3340db4 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 15 Oct 2017 00:05:11 +0300 Subject: [PATCH 088/331] fix --- 2-ui/4-forms-controls/2-focus-blur/article.md | 1 + 1 file changed, 1 insertion(+) diff --git a/2-ui/4-forms-controls/2-focus-blur/article.md b/2-ui/4-forms-controls/2-focus-blur/article.md index d829fb36..694d31cf 100644 --- a/2-ui/4-forms-controls/2-focus-blur/article.md +++ b/2-ui/4-forms-controls/2-focus-blur/article.md @@ -30,6 +30,7 @@ In the example below: Your email please: +
From 07d1188bfa82f1c0ca828b940bb86ebb04d3389f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 15 Oct 2017 00:07:07 +0300 Subject: [PATCH 089/331] minor --- 2-ui/4-forms-controls/2-focus-blur/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/4-forms-controls/2-focus-blur/article.md b/2-ui/4-forms-controls/2-focus-blur/article.md index 694d31cf..06bac479 100644 --- a/2-ui/4-forms-controls/2-focus-blur/article.md +++ b/2-ui/4-forms-controls/2-focus-blur/article.md @@ -30,7 +30,6 @@ In the example below: Your email please: -
@@ -69,6 +68,7 @@ For instance, let's make the visitor unable to leave the input if the value is i Your email please: + ```smart header="Edge spaces and in-between empty text are usually hidden in tools" -Browser tools (to be covered soon) that work with DOM usually do not show spaces at start/end of the text and empty text nodes (line-breaks) between tags. . +Browser tools (to be covered soon) that work with DOM usually do not show spaces at the start/end of the text and empty text nodes (line-breaks) between tags. That's because they are mainly used to decorate HTML, and do not affect (in most cases) how it is shown. @@ -143,7 +143,7 @@ let node5 = {"name":"TABLE","nodeType":1,"children":[{"name":"TBODY","nodeType": drawHtmlTree(node5, 'div.domtree', 600, 200); -You see? The `` has appeared out of nowhere. Should keep in mind while working with tables to evade surprises. +You see? The `` has appeared out of nowhere. Should keep in mind while working with tables to avoid surprises. ```` ## Other node types @@ -193,7 +193,7 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu ## See it yourself -To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up DOM at instant. +To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up DOM at an instant. ## In the browser inspector @@ -207,9 +207,9 @@ Should look like this: You can see the DOM, click on elements, see their details and so on. -Please note that the DOM structure in developer tools is simplified. Text nodes are shown just as text. And there are no "blank" (space only) text nodes at all. That's fine, because most of time we are interested in element nodes. +Please note that the DOM structure in developer tools is simplified. Text nodes are shown just as text. And there are no "blank" (space only) text nodes at all. That's fine, because most of the time we are interested in element nodes. -Clicking the button in the left-upper corner allows to choose a node from the webpage using a mouse (or other pointer device) and "inspect" it (scroll to it in the elements tab). Works great when we have a huge HTML page and would like to see the DOM of a particular place in it. +Clicking the button in the left-upper corner allows to choose a node from the webpage using a mouse (or other pointer devices) and "inspect" it (scroll to it in the elements tab). Works great when we have a huge HTML page and would like to see the DOM of a particular place in it. Another way to do it would be just right-clicking on a webpage and selecting "Inspect" in the context menu. From f03a0edcb49c4260e7e05cdf28043684d19e7b73 Mon Sep 17 00:00:00 2001 From: Hari Shekhar Date: Tue, 28 Nov 2017 11:05:33 +0530 Subject: [PATCH 148/331] Modified just a small comment --- 1-js/05-data-types/09-destructuring-assignment/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/05-data-types/09-destructuring-assignment/article.md b/1-js/05-data-types/09-destructuring-assignment/article.md index a1fb7d54..085d2b8c 100644 --- a/1-js/05-data-types/09-destructuring-assignment/article.md +++ b/1-js/05-data-types/09-destructuring-assignment/article.md @@ -478,8 +478,8 @@ Please note that such destructuring assumes that `showMenu()` does have an argum ```js showMenu({}); -// that would give an error -showMenu(); + +showMenu(); // this would give an error ``` We can fix this by making `{}` the default value for the whole destructuring thing: From 1b10c359bfac9041a2f3db503f044236b8b5ae11 Mon Sep 17 00:00:00 2001 From: Tom Byrer Date: Wed, 29 Nov 2017 04:32:43 -0600 Subject: [PATCH 149/331] consistent code style First the Function function string had no spaces or trailing semi, then did in the second half. Perhaps a linter bot would be better, but manual will do for now. --- 1-js/06-advanced-functions/07-new-function/article.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/1-js/06-advanced-functions/07-new-function/article.md b/1-js/06-advanced-functions/07-new-function/article.md index 73805745..b9d6d1ca 100644 --- a/1-js/06-advanced-functions/07-new-function/article.md +++ b/1-js/06-advanced-functions/07-new-function/article.md @@ -109,7 +109,7 @@ The "sum" function actually does that right: ```js run *!* -let sum = new Function('a', 'b', ' return a + b; '); +let sum = new Function('a', 'b', 'return a + b'); */!* let a = 1, b = 2; @@ -133,9 +133,9 @@ For historical reasons, arguments can also be given as a comma-separated list. These three mean the same: ```js -new Function('a', 'b', ' return a + b; '); // basic syntax -new Function('a,b', ' return a + b; '); // comma-separated -new Function('a , b', ' return a + b; '); // comma-separated with spaces +new Function('a', 'b', 'return a + b'); // basic syntax +new Function('a,b', 'return a + b'); // comma-separated +new Function('a , b', 'return a + b'); // comma-separated with spaces ``` Functions created with `new Function`, have `[[Environment]]` referencing the global Lexical Environment, not the outer one. Hence, they can not use outer variables. But that's actually good, because it saves us from errors. Explicit parameters passing is a much better thing architecturally and has no problems with minifiers. From 28982750047a6fd8acca5ca27d10cf22ed57b636 Mon Sep 17 00:00:00 2001 From: Julie Kim Date: Wed, 29 Nov 2017 10:32:47 -0500 Subject: [PATCH 150/331] "Start with the two" Change to => "Start with two" Minor English grammar issue --- 1-js/02-first-steps/02-structure/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md index fc1dc46e..e9e2e0f9 100644 --- a/1-js/02-first-steps/02-structure/article.md +++ b/1-js/02-first-steps/02-structure/article.md @@ -102,7 +102,7 @@ As time goes on, the program becomes more and more complex. It becomes necessary Comments can be put into any place of the script. They don't affect the execution, because the engine simply ignores them. -**One-line comments start with the two forward slash characters `//`.** +**One-line comments start with two forward slash characters `//`.** The rest of the line is a comment. It may occupy a full line of its own or follow a statement. From c193de977fddc216452b115a4635507ceacbbe09 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 30 Nov 2017 18:12:50 +0300 Subject: [PATCH 151/331] Update article.md --- 2-ui/1-document/03-dom-navigation/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md index b46467c3..b58f15fe 100644 --- a/2-ui/1-document/03-dom-navigation/article.md +++ b/2-ui/1-document/03-dom-navigation/article.md @@ -88,7 +88,7 @@ For instance, here `` has children `
` and `
    ` (and few blank text ``` -...And if we ask for all descendants of ``, then we get direct children `
    `, `
      ` and also more nested elements like `
    • ` (being a child of `
        `) and `` (being a child of `
      • `) -- the whole subtree. +...And if we ask for all descendants of ``, then we get direct children `
        `, `
          ` and also more nested elements like `
        • ` (being a child of `
            `) and `` (being a child of `
          • `) -- the entire subtree. **The `childNodes` collection provides access to all child nodes, including text nodes.** @@ -177,7 +177,7 @@ Please, don't. The `for..in` loop iterates over all enumerable properties. And c ```` @@ -242,7 +242,7 @@ In other words, the `documentElement` (``) is the root node. Formally, it Sometimes that matters when we're walking over the chain of parents and call a method on each of them, but `document` doesn't have it, so we exclude it. ```` -Let's modify one of examples above: replace `childNodes` with `children`. Now it shows only elements: +Let's modify one of the examples above: replace `childNodes` with `children`. Now it shows only elements: ```html run From b2f7515c5db6dee1e58064324becf525fc6c2264 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 30 Nov 2017 18:56:37 +0300 Subject: [PATCH 152/331] Update article.md --- 2-ui/1-document/04-searching-elements-dom/article.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md index 50674218..e7382a01 100644 --- a/2-ui/1-document/04-searching-elements-dom/article.md +++ b/2-ui/1-document/04-searching-elements-dom/article.md @@ -84,7 +84,7 @@ let divs = document.getElementsByTagName('div'); This method is callable in the context of any DOM element. -Let's find all `input` inside the table: +Let's find all `input` tags inside the table: ```html run height=50 @@ -123,16 +123,16 @@ The `"s"` letter is absent in `getElementById`, because it returns a single elem ``` ````warn header="It returns a collection, not an element!" -Another widespread novice mistake is to write like: +Another widespread novice mistake is to write: ```js // doesn't work document.getElementsByTagName('input').value = 5; ``` -That won't work, because it takes a *collection* of inputs and assigns the value to it, rather to elements inside it. +That won't work, because it takes a *collection* of inputs and assigns the value to it rather than to elements inside it. -We should either iterate over the collection or get an element by the number, and then assign, like this: +We should either iterate over the collection or get an element by its index, and then assign, like this: ```js // should work (if there's an input) @@ -374,7 +374,7 @@ Other methods can be called on elements too. For instance `elem.querySelectorAll Besides that: - There is `elem.matches(css)` to check if `elem` matches the given CSS selector. -- There is `elem.closest(css)` to look for a nearest ancestor that matches the given CSS-selector. The `elem` itself is also checked. +- There is `elem.closest(css)` to look for the nearest ancestor that matches the given CSS-selector. The `elem` itself is also checked. And let's mention one more method here to check for the child-parent relationship: - `elemA.contains(elemB)` returns true if `elemB` is inside `elemA` (a descendant of `elemA`) or when `elemA==elemB`. From 26faaacdb73a636915aada6012b94f0620f754b1 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 30 Nov 2017 19:00:59 +0300 Subject: [PATCH 153/331] Update solution.md --- .../04-searching-elements-dom/2-tree-info/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md index 5bb2effa..781b7a92 100644 --- a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md +++ b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md @@ -1,7 +1,7 @@ Let's make a loop over `
          • `: ```js -for (let li of document.querySelector('li')) { +for (let li of document.querySelectorAll('li')) { ... } ``` @@ -9,7 +9,7 @@ for (let li of document.querySelector('li')) { In the loop we need to get the text inside every `li`. We can read it directly from the first child node, that is the text node: ```js -for (let li of document.querySelector('li')) { +for (let li of document.querySelectorAll('li')) { let title = li.firstChild.data; // title is the text in
          • before any other nodes From 299ed0fc3b8d8f7cb2f8ccea08898c0a1e9749c1 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 30 Nov 2017 19:03:40 +0300 Subject: [PATCH 154/331] Update index.html --- .../2-tree-info/solution.view/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html index d712bb9d..5947ec09 100644 --- a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html +++ b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html @@ -40,7 +40,7 @@ @@ -144,9 +144,9 @@ Please note: ## Property-attribute synchronization -When a standard attribute changes, the corresponding property is auto-updated, and (with some exceptions) vise-versa. +When a standard attribute changes, the corresponding property is auto-updated, and (with some exceptions) vice versa. -In the example below `id` is modified as an attribute, and we can see the property change too. And then the same backwards: +In the example below `id` is modified as an attribute, and we can see the property changed too. And then the same backwards: ```html run @@ -188,7 +188,7 @@ In the example above: - Changing the attribute `value` updates the property. - But the property change does not affect the attribute. -That "feature" may actually can come in handy, because the user may modify `value`, and then after it, if we want to recover the "original" value from HTML, it's in the attribute. +That "feature" may actually come in handy, because the user may modify `value`, and then after it, if we want to recover the "original" value from HTML, it's in the attribute. ## DOM properties are typed @@ -311,7 +311,7 @@ div.setAttribute('order-state', 'canceled'); But there may be a possible problem with custom attributes. What if we use a non-standard attribute for our purposes and later the standard introduces it and makes it do something? The HTML language is alive, it grows, more attributes appear to suit the needs of developers. There may be unexpected effects in such case. -To evade conflicts, there exist [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) attributes. +To avoid conflicts, there exist [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) attributes. **All attributes starting with "data-" are reserved for programmers' use. They are available in `dataset` property.** From d147d4b154779a2de929122f0faec3f5bdf12033 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 6 Dec 2017 05:20:36 +0300 Subject: [PATCH 159/331] Update task.md --- .../1-get-user-attribute/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md b/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md index 0d11ff97..4cdf231b 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/task.md @@ -7,7 +7,7 @@ importance: 5 Write the code to select the element with `data-widget-name` attribute from the document and to read its value. ```html run - + From 0ae23f63930d1b2968984c35a413be57d7743690 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 6 Dec 2017 05:23:03 +0300 Subject: [PATCH 160/331] Update solution.md --- .../1-get-user-attribute/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/solution.md b/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/solution.md index 5d3fe241..0507832f 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/solution.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/1-get-user-attribute/solution.md @@ -1,6 +1,6 @@ ```html run height=100 - + From 04d669208c23c46c7c7d4bdd77b67da419e8ea37 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 6 Dec 2017 10:23:46 +0300 Subject: [PATCH 161/331] Update article.md --- 2-ui/1-document/07-modifying-document/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/2-ui/1-document/07-modifying-document/article.md b/2-ui/1-document/07-modifying-document/article.md index adef6f9f..6680450a 100644 --- a/2-ui/1-document/07-modifying-document/article.md +++ b/2-ui/1-document/07-modifying-document/article.md @@ -10,7 +10,7 @@ First we'll see a simple example and then explain the methods. ## Example: show a message -For the start, let's see how to add a message on the page that looks nicer than `alert`. +For a start, let's see how to add a message on the page that looks nicer than `alert`. Here's how it will look: @@ -153,7 +153,7 @@ These methods are "old school": they exist from the ancient times and we can mee For instance, how to insert *html* if we have it as a string? Or, given a node, how to insert another node *before* it? Of course, all that is doable, but not in an elegant way. -So there exists two other sets of insertion methods to handle all cases easily. +So there exist two other sets of insertion methods to handle all cases easily. ### prepend/append/before/after @@ -279,7 +279,7 @@ The method has two brothers: - `elem.insertAdjacentText(where, text)` -- the same syntax, but a string of `text` in inserted "as text" instead of HTML, - `elem.insertAdjacentElement(where, elem)` -- the same syntax, but inserts an element. -They exist mainly to make the syntax "uniform". In practice, most of time only `insertAdjacentHTML` is used, because for elements and text we have methods `append/prepend/before/after` -- they are shorter to write and can insert nodes/text pieces. +They exist mainly to make the syntax "uniform". In practice, most of the time only `insertAdjacentHTML` is used, because for elements and text we have methods `append/prepend/before/after` -- they are shorter to write and can insert nodes/text pieces. So here's an alternative variant of showing a message: From 384a7b7e9c66fe970bf6d5e438280195d876291e Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 7 Dec 2017 01:13:28 +0300 Subject: [PATCH 162/331] Update article.md --- 2-ui/1-document/08-styles-and-classes/article.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index 1c5f0948..bd3c4a27 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -26,7 +26,7 @@ For other cases, like making the text red, adding a background icon -- describe ## className and classList -Changing a class is one of the most often actions in scripts. +Changing a class is one of the most often used actions in scripts. In the ancient time, there was a limitation in JavaScript: a reserved word like `"class"` could not be an object property. That limitation does not exist now, but at that time it was impossible to have a `"class"` property, like `elem.class`. @@ -76,7 +76,7 @@ Besides that, `classList` is iterable, so we can list all classes like this: ```html run @@ -223,7 +223,7 @@ element : Element to read the value for. pseudo -: A pseudo-element if required, for instance `::before`. An empty string or no argument mean the element itself. +: A pseudo-element if required, for instance `::before`. An empty string or no argument means the element itself. The result is an object with style properties, like `elem.style`, but now with respect to all CSS classes. @@ -250,10 +250,10 @@ For instance: ```smart header="Computed and resolved values" There are two concepts in [CSS](https://drafts.csswg.org/cssom/#resolved-values): -1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. If can look like `height:1em` or `font-size:125%`. +1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. It can look like `height:1em` or `font-size:125%`. 2. A *resolved* style value is the one finally applied to the element. Values like `1em` or `125%` are relative. The browser takes the computed value and makes all units fixed and absolute, for instance: `height:20px` or `font-size:16px`. For geometry properties resolved values may have a floating point, like `width:50.5px`. -Long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed. +A long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed. So nowadays `getComputedStyle` actually returns the resolved value of the property. ``` @@ -283,7 +283,7 @@ Visited links may be colored using `:visited` CSS pseudoclass. But `getComputedStyle` does not give access to that color, because otherwise an arbitrary page could find out whether the user visited a link by creating it on the page and checking the styles. -JavaScript we may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids to apply geometry-changing styles in `:visited`. That's to guarantee that there's no side way for an evil page to test if a link was visited and hence to break the privacy. +JavaScript we may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids to apply geometry-changing styles in `:visited`. That's to guarantee that there's no sideway for an evil page to test if a link was visited and hence to break the privacy. ``` ## Summary From edb081fc6870747d3eb46fc1f33e837e826c5cdf Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 7 Dec 2017 01:16:10 +0300 Subject: [PATCH 163/331] Update index.html --- .../2-create-notification/solution.view/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html b/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html index 5b8a6336..dc4eeec9 100755 --- a/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html +++ b/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html @@ -26,7 +26,7 @@ notification.style.top = top + 'px'; notification.style.right = right + 'px'; - notification.innerHTML = options.html; + notification.innerHTML = html; document.body.append(notification); setTimeout(() => notification.remove(), 1500); From 791578812d3ce61a00f13a1c3d2439218531f2eb Mon Sep 17 00:00:00 2001 From: Julie Kim Date: Fri, 8 Dec 2017 11:03:00 -0500 Subject: [PATCH 164/331] labelled -> labeled Labeled and labelled are both correct spellings, and they mean the same thing. How you spell the word depends on your audience. If you are writing for American readers, labeled is the preferred spelling. In other places, such as Great Britain and Canada, labelled is a more common spelling than labeled. (Taken from https://www.grammarly.com/blog/labeled-labelled) --- 1-js/02-first-steps/04-variables/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index fe50cc52..002449f8 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -99,7 +99,7 @@ There are subtle differences between `let` and `var`, but they do not matter for We can easily grasp the concept of a "variable" if we imagine it as a "box" for data, with a uniquely-named sticker on it. -For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it: +For instance, the variable `message` can be imagined as a box labeled `"message"` with the value `"Hello!"` in it: ![](variable.png) From 7685ff05f88aa07350516765818450a014af42db Mon Sep 17 00:00:00 2001 From: Julie Kim Date: Mon, 11 Dec 2017 11:20:48 -0500 Subject: [PATCH 165/331] minor grammar suggestions --- 1-js/02-first-steps/04-variables/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index fe50cc52..b15082fb 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -99,7 +99,7 @@ There are subtle differences between `let` and `var`, but they do not matter for We can easily grasp the concept of a "variable" if we imagine it as a "box" for data, with a uniquely-named sticker on it. -For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it: +For instance, the variable `message` can be imagined as a box labeled `"message"` with the value `"Hello!"` in it: ![](variable.png) @@ -298,9 +298,9 @@ Please name the variables sensibly. Take time to think if needed. Variable naming is one of the most important and complex skills in programming. A quick glance at variable names can reveal which code is written by a beginner and which by an experienced developer. -In a real project, most of the time is spent on modifying and extending the existing code base, rather than writing something completely separate from scratch. And when we return to the code after some time of doing something else, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names. +In a real project, most of the time is spent on modifying and extending the existing code base, rather than writing something completely separate from scratch. And when we return to the code after some time of doing something else, it's much easier to find information that is well-labeled. Or, in other words, when the variables have good names. -Please spend some time thinking about the right name for a variable before declaring it. That will repay you a lot. +Please spend some time thinking about the right name for a variable before declaring it. This will repay you a lot. Some good-to-follow rules are: From 13520927778f08d77732bf7d4779f6e60d1b9f24 Mon Sep 17 00:00:00 2001 From: Alexander Ogilvie <26034704+a-ogilvie@users.noreply.github.com> Date: Fri, 15 Dec 2017 18:54:58 +0900 Subject: [PATCH 166/331] Small changes for readability I got a little confused in one place (line 191) because the meaning wasn't clear. I also changed a couple of other places to make it read more naturally. --- 1-js/05-data-types/06-iterable/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 1ccbaea0..a21bde31 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -188,7 +188,7 @@ for (let item of arrayLike) {} */!* ``` -What they share in common -- both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. +What do they have in common? Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. ## Array.from @@ -295,8 +295,8 @@ Objects that can be used in `for..of` are called *iterable*. - String iterator knows about surrogate pairs. -Objects that have indexed properties and `length` are called *array-like*. Such objects may also have other properties and methods, but lack built-in methods of arrays. +Objects that have indexed properties and `length` are called *array-like*. Such objects may also have other properties and methods, but lack the built-in methods of arrays. If we look inside the specification -- we'll see that most built-in methods assume that they work with iterables or array-likes instead of "real" arrays, because that's more abstract. -`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and then we can use array methods on it. The optional arguments `mapFn` and `thisArg` allow to apply a function to each item. +`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item. From 84163887c55fe58608a08e3581d448e57c78350e Mon Sep 17 00:00:00 2001 From: Alexander Ogilvie <26034704+a-ogilvie@users.noreply.github.com> Date: Fri, 15 Dec 2017 19:11:22 +0900 Subject: [PATCH 167/331] Small grammatical changes Small changes to improve readability. --- .../07-map-set-weakmap-weakset/article.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/1-js/05-data-types/07-map-set-weakmap-weakset/article.md b/1-js/05-data-types/07-map-set-weakmap-weakset/article.md index e3e28f4f..36c8462a 100644 --- a/1-js/05-data-types/07-map-set-weakmap-weakset/article.md +++ b/1-js/05-data-types/07-map-set-weakmap-weakset/article.md @@ -1,16 +1,16 @@ # Map, Set, WeakMap and WeakSet -Now we know the following complex data structures: +Now we've learned about the following complex data structures: - Objects for storing keyed collections. - Arrays for storing ordered collections. -But that's not enough for real life. That's why there also exist `Map` and `Set`. +But that's not enough for real life. That's why `Map` and `Set` also exist. ## Map -[Map](mdn:js/Map) is a collection of keyed data items. Just like an `Object`. But the main difference is that `Map` allows keys of any type. +[Map](mdn:js/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type. The main methods are: @@ -20,7 +20,7 @@ The main methods are: - `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise. - `map.delete(key)` -- removes the value by the key. - `map.clear()` -- clears the map -- `map.size` -- is the current elements count. +- `map.size` -- returns the current element count. For instance: @@ -76,7 +76,7 @@ alert( visitsCounts[john.id] ); // 123 ```smart header="How `Map` compares keys" -To test values for equivalence, `Map` uses the algorithm [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). It is roughly the same as the strict equality `===`, but the difference is that `NaN` is considered equal to `NaN`. So `NaN` can be used as the key as well. +To test values for equivalence, `Map` uses the algorithm [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). It is roughly the same as strict equality `===`, but the difference is that `NaN` is considered equal to `NaN`. So `NaN` can be used as the key as well. This algorithm can't be changed or customized. ``` @@ -106,7 +106,7 @@ let map = new Map([ ]); ``` -There is a built-in method [Object.entries(obj)](mdn:js/Object/entries) that returns the array of key/value pairs for an object exactly in that format. +There is a built-in method [Object.entries(obj)](mdn:js/Object/entries) that returns an array of key/value pairs for an object exactly in that format. So we can initialize a map from an object like this: @@ -167,9 +167,9 @@ recipeMap.forEach( (value, key, map) => { ## Set -`Set` -- is a collection of values, where each value may occur only once. +A `Set` is a collection of values, where each value may occur only once. -The main methods are: +Its main methods are: - `new Set(iterable)` -- creates the set, optionally from an array of values (any iterable will do). - `set.add(value)` -- adds a value, returns the set itself. @@ -223,9 +223,9 @@ set.forEach((value, valueAgain, set) => { Note the funny thing. The `forEach` function in the `Set` has 3 arguments: a value, then *again a value*, and then the target object. Indeed, the same value appears in the arguments twice. -That's made for compatibility with `Map` where `forEach` has three arguments. +That's for compatibility with `Map` where `forEach` has three arguments. -The same methods as `Map` has for iterators are also supported: +The same methods `Map` has for iterators are also supported: - `set.keys()` -- returns an iterable object for values, - `set.values()` -- same as `set.keys`, for compatibility with `Map`, @@ -330,9 +330,9 @@ weakMap.put(john, "secret documents"); That's useful for situations when we have a main storage for the objects somewhere and need to keep additional information that is only relevant while the object lives. -Let's see an example. +Let's look at an example. -For instance, we have a code that keeps a visit count for each user. The information is stored in a map: a user is the key and the visit count is the value. When a user leaves, we don't want to store his visit count anymore. +For instance, we have code that keeps a visit count for each user. The information is stored in a map: a user is the key and the visit count is the value. When a user leaves, we don't want to store his visit count anymore. One way would be to keep track of leaving users and clean up the storage manually: From 51aff82819ce54f8a1aec3d6edce5486e086e465 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sat, 16 Dec 2017 14:23:54 +0300 Subject: [PATCH 168/331] minor --- 1-js/03-code-quality/04-ninja-code/article.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md index 8ad21003..4ed183fa 100644 --- a/1-js/03-code-quality/04-ninja-code/article.md +++ b/1-js/03-code-quality/04-ninja-code/article.md @@ -1,6 +1,11 @@ # Ninja code -Programmer ninjas of the past used these tricks to make code maintainers cry. + +```quote author="Confucius" +Learning without thought is labor lost; thought without learning is perilous. +``` + +Programmer ninjas of the past used these tricks to make sharpen the mind of code maintainers. Code review gurus look for them in test tasks. @@ -12,7 +17,7 @@ Read them carefully and find out who you are -- a ninja, a novice, or maybe a co ```warn header="Irony detected" -Many start following ninja paths. Few succeed. +Many try to follow ninja paths. Few succeed. ``` From 6e4427dcf079f34c98819f6b18f8412598ea2f99 Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Sun, 17 Dec 2017 00:04:46 +0300 Subject: [PATCH 169/331] minor --- 1-js/03-code-quality/04-ninja-code/article.md | 12 +++++++----- 1-js/04-object-basics/01-object/article.md | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md index 4ed183fa..bc1283aa 100644 --- a/1-js/03-code-quality/04-ninja-code/article.md +++ b/1-js/03-code-quality/04-ninja-code/article.md @@ -45,7 +45,7 @@ The Dao hides in wordlessness. Only the Dao is well begun and well completed. ``` -Another way to code faster (and much worse!) is to use single-letter variable names everywhere. Like `a`, `b` or `c`. +Another way to code faster is to use single-letter variable names everywhere. Like `a`, `b` or `c`. A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using "search" of the editor. And even if someone does, he won't be able to "decipher" what the name `a` or `b` means. @@ -83,17 +83,19 @@ While choosing a name try to use the most abstract word. Like `obj`, `data`, `va - **Name a variable by its type: `str`, `num`...** - Give them a try. A young ninja may wonder -- do such names make the code worse? Actually, yes! + Give them a try. A young initiate may wonder -- are such names really useful for a ninja? Indeed, they are! - Sure, the variable name still means something. It says what's inside the variable: a string, a number or something else. But when an outsider tries to understand the code, he'll be surprised to see that there's actually no information at all! + Sure, the variable name still means something. It says what's inside the variable: a string, a number or something else. But when an outsider tries to understand the code, he'll be surprised to see that there's actually no information at all! And will ultimately fail to alter your well-thought code. - Indeed, the value type is easy to find out by debugging. But what's the meaning of the variable? Which string/number does it store? There's just no way to figure out without a good meditation! + The value type is easy to find out by debugging. But what's the meaning of the variable? Which string/number does it store? + + There's just no way to figure out without a good meditation! - **...But what if there are no more such names?** Just add a number: `data1, item2, elem5`... ## Attention test -Only a truly attentive programmer should be able to understand the code. But how to check that? +Only a truly attentive programmer should be able to understand your code. But how to check that? **One of the ways -- use similar variable names, like `date` and `data`.** diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index 31e164d9..91095489 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -228,7 +228,7 @@ That can become a source of bugs and even vulnerabilies if we intent to store ar In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). -There exist a way to make objects treat `__proto__` as a regular property, we'll cover it later, but first we need to know more about objects to understand it. +There exist a way to make objects treat `__proto__` as a regular property, we'll cover it later, but first we need to know more about objects to understand it. There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. Also ```` @@ -411,8 +411,8 @@ So, "49" is an integer property name, because when it's transformed to an intege ```js run // Math.trunc is a built-in function that removes the decimal part alert( String(Math.trunc(Number("49"))) ); // "49", same, integer property -alert( String(Math.trunc(Number("+49"))) ); // "49", not same ⇒ not integer property -alert( String(Math.trunc(Number("1.2"))) ); // "1", not same ⇒ not integer property +alert( String(Math.trunc(Number("+49"))) ); // "49", not same "+49" ⇒ not integer property +alert( String(Math.trunc(Number("1.2"))) ); // "1", not same "1.2" ⇒ not integer property ``` ```` From 01d9f8297cf93431febfb740a21bd1d0ecf0cd58 Mon Sep 17 00:00:00 2001 From: Benjamin Modayil Date: Sun, 17 Dec 2017 11:08:46 -0500 Subject: [PATCH 170/331] rearranged word "also" --- 1-js/04-object-basics/01-object/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index 31e164d9..f9e97eee 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -229,7 +229,7 @@ That can become a source of bugs and even vulnerabilies if we intent to store ar In that case the visitor may choose "__proto__" as the key, and the assignment logic will be ruined (as shown above). There exist a way to make objects treat `__proto__` as a regular property, we'll cover it later, but first we need to know more about objects to understand it. -There's another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. Also +There's also another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys. ```` From c1e4507c8e27279c52338d94340dfb63fb972c6f Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Wed, 20 Dec 2017 20:31:18 +0300 Subject: [PATCH 171/331] minor --- .../10-onload-ondomcontentloaded/article.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md b/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md index 277b70ef..11305212 100644 --- a/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md +++ b/2-ui/3-event-details/10-onload-ondomcontentloaded/article.md @@ -128,28 +128,24 @@ For that we should use another event -- `onbeforeunload`. ## window.onbeforeunload [#window.onbeforeunload] -If a visitor initiated leaving the page or tries to close the window, the `beforeunload` handler can ask for additional confirmation. +If a visitor initiated navigation away from the page or tries to close the window, the `beforeunload` handler asks for additional confirmation. -It needs to return the string with the question. The browser will show it. +It may return a string with the question. Historically browsers used to show it, but as of now only some of them do. That's because certain webmasters abused this event handler, to protect the visitor from potentially misleading and hackish messages. -For instance: +You can try it by running this code and then reloading the page. -```js +```js run window.onbeforeunload = function() { return "There are unsaved changes. Leave now?"; }; ``` ```online -Click on the button in `