minor
This commit is contained in:
parent
9b95b5ee0e
commit
061ff30189
4 changed files with 42 additions and 33 deletions
|
@ -17,9 +17,9 @@ Write the destructuring assignment that reads:
|
||||||
|
|
||||||
- `name` property into the variable `name`.
|
- `name` property into the variable `name`.
|
||||||
- `years` property into the variable `age`.
|
- `years` property into the variable `age`.
|
||||||
- `isAdmin` property into the variable `isAdmin` (false if absent)
|
- `isAdmin` property into the variable `isAdmin` (false, if no such property)
|
||||||
|
|
||||||
The values after the assignment should be:
|
Here's an example of the values after your assignment:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let user = { name: "John", years: 30 };
|
let user = { name: "John", years: 30 };
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
The two most used data structures in JavaScript are `Object` and `Array`.
|
The two most used data structures in JavaScript are `Object` and `Array`.
|
||||||
|
|
||||||
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.
|
Objects allow us to create a single entity that stores data items by key, and arrays allow us to gather data items into an ordered collection.
|
||||||
|
|
||||||
*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.
|
But when we pass those to a function, it may need not an object/array as a whole, but rather individual pieces.
|
||||||
|
|
||||||
|
*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient. Destructuring also works great with complex functions that have a lot of parameters, default values, and so on.
|
||||||
|
|
||||||
## Array destructuring
|
## Array destructuring
|
||||||
|
|
||||||
|
@ -16,6 +18,8 @@ let arr = ["Ilya", "Kantor"]
|
||||||
|
|
||||||
*!*
|
*!*
|
||||||
// destructuring assignment
|
// destructuring assignment
|
||||||
|
// sets firstName = arr[0]
|
||||||
|
// and surname = arr[1]
|
||||||
let [firstName, surname] = arr;
|
let [firstName, surname] = arr;
|
||||||
*/!*
|
*/!*
|
||||||
|
|
||||||
|
@ -54,7 +58,7 @@ let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic
|
||||||
alert( title ); // Consul
|
alert( title ); // Consul
|
||||||
```
|
```
|
||||||
|
|
||||||
In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array is also skipped.
|
In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items is also skipped (as there are no variables for them).
|
||||||
````
|
````
|
||||||
|
|
||||||
````smart header="Works with any iterable on the right-side"
|
````smart header="Works with any iterable on the right-side"
|
||||||
|
@ -111,7 +115,7 @@ user.set("name", "John");
|
||||||
user.set("age", "30");
|
user.set("age", "30");
|
||||||
|
|
||||||
*!*
|
*!*
|
||||||
for (let [key, value] of user.entries()) {
|
for (let [key, value] of user) {
|
||||||
*/!*
|
*/!*
|
||||||
alert(`${key}:${value}`); // name:John, then age:30
|
alert(`${key}:${value}`); // name:John, then age:30
|
||||||
}
|
}
|
||||||
|
@ -209,7 +213,7 @@ alert(height); // 200
|
||||||
Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. The order does not matter. This 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
|
```js
|
||||||
// changed the order of properties in let {...}
|
// changed the order in let {...}
|
||||||
let {height, width, title} = { title: "Menu", height: 200, width: 100 }
|
let {height, width, title} = { title: "Menu", height: 200, width: 100 }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -293,7 +297,7 @@ alert(h); // 200
|
||||||
|
|
||||||
What if the object has more properties than we have variables? Can we take some and then assign the "rest" somewhere?
|
What if the object has more properties than we have variables? Can we take some and then assign the "rest" somewhere?
|
||||||
|
|
||||||
The specification for using the rest operator (three dots) here is almost in the standard, but most browsers do not support it yet.
|
Using the rest operator with objects is not supported by some older browsers (use Babel to polyfill it), but works in modern ones.
|
||||||
|
|
||||||
It looks like this:
|
It looks like this:
|
||||||
|
|
||||||
|
@ -305,6 +309,8 @@ let options = {
|
||||||
};
|
};
|
||||||
|
|
||||||
*!*
|
*!*
|
||||||
|
// title = property named title
|
||||||
|
// rest = object with the rest of properties
|
||||||
let {title, ...rest} = options;
|
let {title, ...rest} = options;
|
||||||
*/!*
|
*/!*
|
||||||
|
|
||||||
|
@ -315,8 +321,8 @@ alert(rest.width); // 100
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
````smart header="Gotcha without `let`"
|
````smart header="Gotcha if there's no `let`"
|
||||||
In the examples above variables were declared right before the assignment: `let {…} = {…}`. Of course, we could use existing variables too. But there's a catch.
|
In the examples above variables were declared right in the assignment: `let {…} = {…}`. Of course, we could use existing variables too, without `let`. But there's a catch.
|
||||||
|
|
||||||
This won't work:
|
This won't work:
|
||||||
```js run
|
```js run
|
||||||
|
@ -337,13 +343,13 @@ The problem is that JavaScript treats `{...}` in the main code flow (not inside
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To show JavaScript that it's not a code block, we can wrap the whole assignment in parentheses `(...)`:
|
To show JavaScript that it's not a code block, we can make it a part of an expression by wrapping in parentheses `(...)`:
|
||||||
|
|
||||||
```js run
|
```js run
|
||||||
let title, width, height;
|
let title, width, height;
|
||||||
|
|
||||||
// okay now
|
// okay now
|
||||||
*!*(*/!*{title, width, height} = {title: "Menu", width: 200, height: 100}*!*)*/!*;
|
*!*(*/!*{title, width, height}*!*)*/!* = {title: "Menu", width: 200, height: 100};
|
||||||
|
|
||||||
alert( title ); // Menu
|
alert( title ); // Menu
|
||||||
```
|
```
|
||||||
|
@ -366,7 +372,7 @@ let options = {
|
||||||
extra: true // something extra that we will not destruct
|
extra: true // something extra that we will not destruct
|
||||||
};
|
};
|
||||||
|
|
||||||
// destructuring assignment on multiple lines for clarity
|
// destructuring assignment split in multiple lines for clarity
|
||||||
let {
|
let {
|
||||||
size: { // put size here
|
size: { // put size here
|
||||||
width,
|
width,
|
||||||
|
@ -391,9 +397,8 @@ Note that `size` and `items` itself is not destructured.
|
||||||
|
|
||||||
Finally, we have `width`, `height`, `item1`, `item2` and `title` from the default value.
|
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 many properties and want to extract only what we need.
|
If we have a complex object with many properties, we can extract only what we need:
|
||||||
|
|
||||||
Even here it happens:
|
|
||||||
```js
|
```js
|
||||||
// take size as a whole into a variable, ignore the rest
|
// take size as a whole into a variable, ignore the rest
|
||||||
let { size } = options;
|
let { size } = options;
|
||||||
|
@ -401,7 +406,7 @@ let { size } = options;
|
||||||
|
|
||||||
## Smart function parameters
|
## Smart function parameters
|
||||||
|
|
||||||
There are times when a function may have many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, items list and so on.
|
There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, items list and so on.
|
||||||
|
|
||||||
Here's a bad way to write such function:
|
Here's a bad way to write such function:
|
||||||
|
|
||||||
|
@ -503,11 +508,13 @@ In the code above, the whole arguments object is `{}` by default, so there's alw
|
||||||
- Destructuring assignment allows for instantly mapping an object or array onto many variables.
|
- Destructuring assignment allows for instantly mapping an object or array onto many variables.
|
||||||
- The object syntax:
|
- The object syntax:
|
||||||
```js
|
```js
|
||||||
let {prop : varName = default, ...} = object
|
let {prop : varName = default, ...rest} = object
|
||||||
```
|
```
|
||||||
|
|
||||||
This means that property `prop` should go into the variable `varName` and, if no such property exists, then the `default` value should be used.
|
This means that property `prop` should go into the variable `varName` and, if no such property exists, then the `default` value should be used.
|
||||||
|
|
||||||
|
Object properties that have no mapping are copied to the `rest` object.
|
||||||
|
|
||||||
- The array syntax:
|
- The array syntax:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
There are two kinds of properties.
|
There are two kinds of properties.
|
||||||
|
|
||||||
The first kind is *data properties*. We already know how to work with them. Actually, all properties that we've been using till now were data properties.
|
The first kind is *data properties*. We already know how to work with them. All properties that we've been using till now were data properties.
|
||||||
|
|
||||||
The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code.
|
The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code.
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ alert(user.name); // Alice
|
||||||
alert(user.surname); // Cooper
|
alert(user.surname); // Cooper
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we have a "virtual" property. It is readable and writable, but in fact does not exist.
|
As the result, we have a "virtual" property `fullName`. It is readable and writable, but in fact does not exist.
|
||||||
|
|
||||||
```smart header="Accessor properties are only accessible with get/set"
|
```smart header="Accessor properties are only accessible with get/set"
|
||||||
Once a property is defined with `get prop()` or `set prop()`, it's an accessor property, not a data property any more.
|
Once a property is defined with `get prop()` or `set prop()`, it's an accessor property, not a data property any more.
|
||||||
|
@ -181,9 +181,9 @@ Technically, the external code may still access the name directly by using `user
|
||||||
|
|
||||||
## Using for compatibility
|
## Using for compatibility
|
||||||
|
|
||||||
One of the great ideas behind getters and setters -- they allow to take control over a "normal" data property and tweak it at any moment.
|
One of the great ideas behind getters and setters -- they allow to take control over a "regular" data property at any moment by replacing it with getter and setter and tweak its behavior.
|
||||||
|
|
||||||
For instance, we started implementing user objects using data properties `name` and `age`:
|
Let's say we started implementing user objects using data properties `name` and `age`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function User(name, age) {
|
function User(name, age) {
|
||||||
|
@ -209,9 +209,9 @@ let john = new User("John", new Date(1992, 6, 1));
|
||||||
|
|
||||||
Now what to do with the old code that still uses `age` property?
|
Now what to do with the old code that still uses `age` property?
|
||||||
|
|
||||||
We can try to find all such places and fix them, but that takes time and can be hard to do if that code is written by other people. And besides, `age` is a nice thing to have in `user`, right? In some places it's just what we want.
|
We can try to find all such places and fix them, but that takes time and can be hard to do if that code is written/used by many other people. And besides, `age` is a nice thing to have in `user`, right? In some places it's just what we want.
|
||||||
|
|
||||||
Adding a getter for `age` mitigates the problem:
|
Adding a getter for `age` solves the problem:
|
||||||
|
|
||||||
```js run no-beautify
|
```js run no-beautify
|
||||||
function User(name, birthday) {
|
function User(name, birthday) {
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
Forms and control elements, such as `<input>` have a lot of special properties and events.
|
Forms and control elements, such as `<input>` have a lot of special properties and events.
|
||||||
|
|
||||||
Working with forms can be much more convenient if we know them.
|
Working with forms will be much more convenient when we learn them.
|
||||||
|
|
||||||
## Navigation: form and elements
|
## Navigation: form and elements
|
||||||
|
|
||||||
Document forms are members of the special collection `document.forms`.
|
Document forms are members of the special collection `document.forms`.
|
||||||
|
|
||||||
That's a *named* collection: we can use both the name and the number to get the form.
|
That's a so-called "named collection": it's both named and ordered. We can use both the name or the number in the document to get the form.
|
||||||
|
|
||||||
```js no-beautify
|
```js no-beautify
|
||||||
document.forms.my - the form with name="my"
|
document.forms.my - the form with name="my"
|
||||||
|
@ -154,7 +154,7 @@ Let's talk about form controls, pay attention to their specific features.
|
||||||
|
|
||||||
### input and textarea
|
### input and textarea
|
||||||
|
|
||||||
Normally, we can access the value as `input.value` or `input.checked` for checkboxes.
|
We can access their value as `input.value` (string) or `input.checked` (boolean) for checkboxes.
|
||||||
|
|
||||||
Like this:
|
Like this:
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ input.checked = true; // for a checkbox or radio button
|
||||||
```
|
```
|
||||||
|
|
||||||
```warn header="Use `textarea.value`, not `textarea.innerHTML`"
|
```warn header="Use `textarea.value`, not `textarea.innerHTML`"
|
||||||
Please note that we should never use `textarea.innerHTML`: it stores only the HTML that was initially on the page, not the current value.
|
Please note that even though `<textarea>...</textarea>` holds its value as nested HTML, we should never use `textarea.innerHTML`. It stores only the HTML that was initially on the page, not the current value.
|
||||||
```
|
```
|
||||||
|
|
||||||
### select and option
|
### select and option
|
||||||
|
@ -174,8 +174,8 @@ Please note that we should never use `textarea.innerHTML`: it stores only the HT
|
||||||
A `<select>` element has 3 important properties:
|
A `<select>` element has 3 important properties:
|
||||||
|
|
||||||
1. `select.options` -- the collection of `<option>` elements,
|
1. `select.options` -- the collection of `<option>` elements,
|
||||||
2. `select.value` -- the value of the chosen option,
|
2. `select.value` -- the value of the currently selected option,
|
||||||
3. `select.selectedIndex` -- the number of the selected option.
|
3. `select.selectedIndex` -- the number of the currently selected option.
|
||||||
|
|
||||||
So we have three ways to set the value of a `<select>`:
|
So we have three ways to set the value of a `<select>`:
|
||||||
|
|
||||||
|
@ -223,10 +223,12 @@ Like this:
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
The full specification of the `<select>` element is available at <https://html.spec.whatwg.org/multipage/forms.html#the-select-element>.
|
The full specification of the `<select>` element is available in the specification <https://html.spec.whatwg.org/multipage/forms.html#the-select-element>.
|
||||||
|
|
||||||
### new Option
|
### new Option
|
||||||
|
|
||||||
|
This is rarely used on its own. But there's still an interesting thing.
|
||||||
|
|
||||||
In the specification of [the option element](https://html.spec.whatwg.org/multipage/forms.html#the-option-element) there's a nice short syntax to create `<option>` elements:
|
In the specification of [the option element](https://html.spec.whatwg.org/multipage/forms.html#the-option-element) there's a nice short syntax to create `<option>` elements:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -237,7 +239,7 @@ Parameters:
|
||||||
|
|
||||||
- `text` -- the text inside the option,
|
- `text` -- the text inside the option,
|
||||||
- `value` -- the option value,
|
- `value` -- the option value,
|
||||||
- `defaultSelected` -- if `true`, then `selected` attribute is created,
|
- `defaultSelected` -- if `true`, then `selected` HTML-attribute is created,
|
||||||
- `selected` -- if `true`, then the option is selected.
|
- `selected` -- if `true`, then the option is selected.
|
||||||
|
|
||||||
For instance:
|
For instance:
|
||||||
|
@ -281,6 +283,6 @@ Form navigation:
|
||||||
|
|
||||||
Value is available as `input.value`, `textarea.value`, `select.value` etc, or `input.checked` for checkboxes and radio buttons.
|
Value is available as `input.value`, `textarea.value`, `select.value` etc, or `input.checked` for checkboxes and radio buttons.
|
||||||
|
|
||||||
For `<select>` we can also get the value by the index `select.selectedIndex` or through the options collection `select.options`. The full specification of this and other elements is at <https://html.spec.whatwg.org/multipage/forms.html>.
|
For `<select>` we can also get the value by the index `select.selectedIndex` or through the options collection `select.options`. The full specification of this and other elements is in the specification <https://html.spec.whatwg.org/multipage/forms.html>.
|
||||||
|
|
||||||
These are the basics to start working with forms. In the next chapter we'll cover `focus` and `blur` events that may occur on any element, but are mostly handled on forms.
|
These are the basics to start working with forms. We'll meet many examples further in the tutorial. In the next chapter we'll cover `focus` and `blur` events that may occur on any element, but are mostly handled on forms.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue