diff --git a/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md b/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md index b2213323..b68db5c5 100644 --- a/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md +++ b/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md @@ -17,9 +17,9 @@ Write the destructuring assignment that reads: - `name` property into the variable `name`. - `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 let user = { name: "John", years: 30 }; 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 7c60b274..410e1b40 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,11 @@ 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 @@ -16,6 +18,8 @@ let arr = ["Ilya", "Kantor"] *!* // destructuring assignment +// sets firstName = arr[0] +// and surname = arr[1] let [firstName, surname] = arr; */!* @@ -54,7 +58,7 @@ let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic 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" @@ -111,7 +115,7 @@ user.set("name", "John"); 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 } @@ -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: ```js -// changed the order of properties in let {...} +// changed the order in let {...} 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? -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: @@ -305,6 +309,8 @@ let options = { }; *!* +// title = property named title +// rest = object with the rest of properties let {title, ...rest} = options; */!* @@ -315,8 +321,8 @@ alert(rest.width); // 100 -````smart header="Gotcha without `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. +````smart header="Gotcha if there's no `let`" +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: ```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 let title, width, height; // okay now -*!*(*/!*{title, width, height} = {title: "Menu", width: 200, height: 100}*!*)*/!*; +*!*(*/!*{title, width, height}*!*)*/!* = {title: "Menu", width: 200, height: 100}; alert( title ); // Menu ``` @@ -366,7 +372,7 @@ let options = { 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 { size: { // put size here 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. -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 // take size as a whole into a variable, ignore the rest let { size } = options; @@ -401,7 +406,7 @@ let { size } = options; ## 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: @@ -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. - The object syntax: ```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. + Object properties that have no mapping are copied to the `rest` object. + - The array syntax: ```js diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md index 5b58b584..f316cc23 100644 --- a/1-js/07-object-properties/02-property-accessors/article.md +++ b/1-js/07-object-properties/02-property-accessors/article.md @@ -3,7 +3,7 @@ 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. @@ -82,7 +82,7 @@ alert(user.name); // Alice 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" 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 -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 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? -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 function User(name, birthday) { diff --git a/2-ui/4-forms-controls/1-form-elements/article.md b/2-ui/4-forms-controls/1-form-elements/article.md index 08060c4c..7ee472a9 100644 --- a/2-ui/4-forms-controls/1-form-elements/article.md +++ b/2-ui/4-forms-controls/1-form-elements/article.md @@ -2,13 +2,13 @@ Forms and control elements, such as `` 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 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 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 -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: @@ -166,7 +166,7 @@ input.checked = true; // for a checkbox or radio button ``` ```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 `` 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 @@ -174,8 +174,8 @@ Please note that we should never use `textarea.innerHTML`: it stores only the HT A ``: @@ -223,10 +223,12 @@ Like this: ``` -The full specification of the `` element is available in the specification . ### 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 `