From 4858aaa062c2629a1b08c5603a885c181e1831e1 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 28 Sep 2017 01:18:05 +0300 Subject: [PATCH 01/10] 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 02/10] 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 03/10] 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 04/10] 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 05/10] 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 06/10] 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 07/10] 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 08/10] 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 09/10] 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 10/10] 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 +});