This commit is contained in:
Ilya Kantor 2017-10-02 12:07:14 +03:00
commit 121c264090
9 changed files with 31 additions and 31 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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];
}

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -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

View file

@ -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));
});
});
});

View file

@ -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