Merge branch 'master' of https://github.com/iliakan/javascript-tutorial-en
This commit is contained in:
commit
ffcfda0023
18 changed files with 45 additions and 44 deletions
|
@ -9,13 +9,13 @@ if (userName == 'Admin') {
|
|||
|
||||
if (pass == 'TheMaster') {
|
||||
alert( 'Welcome!' );
|
||||
} else if (pass == null) {
|
||||
} else if (pass == '' || pass == null) {
|
||||
alert( 'Canceled.' );
|
||||
} else {
|
||||
alert( 'Wrong password' );
|
||||
}
|
||||
|
||||
} else if (userName == null) {
|
||||
} else if (userName == '' || userName == null) {
|
||||
alert( 'Canceled' );
|
||||
} else {
|
||||
alert( "I don't know you" );
|
||||
|
|
|
@ -20,4 +20,6 @@ The schema:
|
|||
|
||||
Please use nested `if` blocks. Mind the overall readability of the code.
|
||||
|
||||
Hint: passing an empty input to a prompt returns an empty string `''`. Pressing `key:ESC` during a prompt returns `null`.
|
||||
|
||||
[demo]
|
||||
|
|
|
@ -188,7 +188,7 @@ The same logic using `if..else`:
|
|||
```js
|
||||
if (age < 3) {
|
||||
message = 'Hi, baby!';
|
||||
} else if (a < 18) {
|
||||
} else if (age < 18) {
|
||||
message = 'Hello!';
|
||||
} else if (age < 100) {
|
||||
message = 'Greetings!';
|
||||
|
|
|
@ -83,7 +83,6 @@ let user = {
|
|||

|
||||
|
||||
|
||||
````smart header="Trailing comma"
|
||||
The last property in the list may end with a comma:
|
||||
```js
|
||||
let user = {
|
||||
|
@ -92,7 +91,6 @@ let user = {
|
|||
}
|
||||
```
|
||||
That is called a "trailing" or "hanging" comma. Makes it easier to add/remove/move around properties, because all lines become alike.
|
||||
````
|
||||
|
||||
## Square brackets
|
||||
|
||||
|
@ -226,7 +224,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 is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects.
|
||||
There's also another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter <info:map-set-weakmap-weakset>, which supports arbitrary keys.
|
||||
````
|
||||
|
||||
|
@ -370,7 +368,7 @@ Also, we could use another variable name here instead of `key`. For instance, `"
|
|||
|
||||
### Ordered like an object
|
||||
|
||||
Are objects ordered? In other words, if we loop over an object, do we get all properties in the same order that they are added in it? Can we rely on it?
|
||||
Are objects ordered? In other words, if we loop over an object, do we get all properties in the same order they were added? Can we rely on this?
|
||||
|
||||
The short answer is: "ordered in a special fashion": integer properties are sorted, others appear in creation order. The details follow.
|
||||
|
||||
|
@ -514,7 +512,7 @@ admin.name = 'Pete'; // changed by the "admin" reference
|
|||
alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference
|
||||
```
|
||||
|
||||
The example above demonstrates that there is only one object. Like if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use the other key (`user`) we would see changes.
|
||||
The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use the other key (`user`) we would see changes.
|
||||
|
||||
### Comparison by reference
|
||||
|
||||
|
@ -541,7 +539,7 @@ let b = {}; // two independent objects
|
|||
alert( a == b ); // false
|
||||
```
|
||||
|
||||
For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to say the truth, such comparisons are necessary very rarely and usually are a result of a coding mistake.
|
||||
For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are necessary very rarely and usually are a result of a coding mistake.
|
||||
|
||||
### Const object
|
||||
|
||||
|
@ -739,4 +737,4 @@ There are many other kinds of objects in JavaScript:
|
|||
|
||||
They have their special features that we'll study later. Sometimes people say something like "Array type" or "Date type", but formally they are not types of their own, but belong to a single "object" data type. And they extend it in various ways.
|
||||
|
||||
Objects in JavaScript are very powerful. Here we've just scratched the surface of the topic that is really huge. We'll be closely working with objects and learning more about them in further parts of the tutorial.
|
||||
Objects in JavaScript are very powerful. Here we've just scratched the surface of a topic that is really huge. We'll be closely working with objects and learning more about them in further parts of the tutorial.
|
||||
|
|
|
@ -138,7 +138,7 @@ let recipeMap = new Map([
|
|||
|
||||
// iterate over keys (vegetables)
|
||||
for (let vegetable of recipeMap.keys()) {
|
||||
alert(vegetable); // cucumber, tomateos, onion
|
||||
alert(vegetable); // cucumber, tomatoes, onion
|
||||
}
|
||||
|
||||
// iterate over values (amounts)
|
||||
|
|
|
@ -95,7 +95,7 @@ user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinu
|
|||
|
||||
user.sayNow("Hello");
|
||||
// Something like:
|
||||
// [10:00] Hello, John!
|
||||
// [10:00] John: Hello!
|
||||
```
|
||||
|
||||
The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that calls `func` with:
|
||||
|
|
|
@ -128,7 +128,7 @@ Object.defineProperty(user, 'fullName', {
|
|||
|
||||
alert(user.fullName); // John Smith
|
||||
|
||||
for(let key in user) alert(key);
|
||||
for(let key in user) alert(key); // name, surname
|
||||
```
|
||||
|
||||
Please note once again that a property can be either an accessor or a data property, not both.
|
||||
|
|
|
@ -295,7 +295,7 @@ try {
|
|||
|
||||
As we can see, that's a `SyntaxError`.
|
||||
|
||||
And in our case, the absense of `name` could be treated as a syntax error also, assuming that users must have a `name`.
|
||||
And in our case, the absence of `name` could be treated as a syntax error also, assuming that users must have a `name`.
|
||||
|
||||
So let's throw it:
|
||||
|
||||
|
|
|
@ -80,8 +80,8 @@ Browser Object Model (BOM) are additional objects provided by the browser (host
|
|||
|
||||
For instance:
|
||||
|
||||
- [navigator](mdn:api/Window/navigator) object provides background information about the browser and the operating system. There are many properties, but the two most widely known are: `navigator.userAgent` -- about the current browser, and `navigator.platform` -- about the platform (can help to differ between Windows/Linux/Mac etc).
|
||||
- [location](mdn:api/Window/location) object allows us to read the current URL and can redirect the browser to a new one.
|
||||
- The [navigator](mdn:api/Window/navigator) object provides background information about the browser and the operating system. There are many properties, but the two most widely known are: `navigator.userAgent` -- about the current browser, and `navigator.platform` -- about the platform (can help to differ between Windows/Linux/Mac etc).
|
||||
- The [location](mdn:api/Window/location) object allows us to read the current URL and can redirect the browser to a new one.
|
||||
|
||||
Here's how we can use the `location` object:
|
||||
|
||||
|
@ -112,7 +112,7 @@ CSSOM specification
|
|||
: Describes stylesheets and style rules, manipulations with them and their binding to documents, see <https://www.w3.org/TR/cssom-1/>.
|
||||
|
||||
HTML specification
|
||||
: Describes HTML language (tags etc.) and also BOM (browser object model) -- various browser functions: `setTimeout`, `alert`, `location` and so on, see <https://html.spec.whatwg.org>. It takes DOM specification and extends it with many additional properties and methods.
|
||||
: Describes the HTML language (e.g. tags) and also the BOM (browser object model) -- various browser functions: `setTimeout`, `alert`, `location` and so on, see <https://html.spec.whatwg.org>. It takes the DOM specification and extends it with many additional properties and methods.
|
||||
|
||||
Now we'll get down to learning DOM, because the document plays the central role in the UI.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ importance: 5
|
|||
|
||||
# What's in the nodeType?
|
||||
|
||||
What the script shows?
|
||||
What does the script show?
|
||||
|
||||
```html
|
||||
<html>
|
||||
|
|
|
@ -4,7 +4,7 @@ importance: 3
|
|||
|
||||
# Tag in comment
|
||||
|
||||
What this code shows?
|
||||
What does this code show?
|
||||
|
||||
```html
|
||||
<script>
|
||||
|
|
|
@ -4,7 +4,7 @@ importance: 4
|
|||
|
||||
# Where's the "document" in the hierarchy?
|
||||
|
||||
Which class the `document` belongs to?
|
||||
Which class does the `document` belong to?
|
||||
|
||||
What's its place in the DOM hierarchy?
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ Try it on `document.body`.
|
|||
```
|
||||
|
||||
````smart header="IDL in the spec"
|
||||
In the specification classes are described using not JavaScript, but a special [Interface description language](https://en.wikipedia.org/wiki/Interface_description_language) (IDL), that is usually easy to understand.
|
||||
In the specification, classes are described not using JavaScript, but a special [Interface description language](https://en.wikipedia.org/wiki/Interface_description_language) (IDL), that is usually easy to understand.
|
||||
|
||||
In IDL all properties are prepended with their types. For instance, `DOMString`, `boolean` and so on.
|
||||
|
||||
|
@ -163,11 +163,11 @@ Sure, the difference is reflected in their names, but is indeed a bit subtle.
|
|||
- The `tagName` property exists only for `Element` nodes.
|
||||
- The `nodeName` is defined for any `Node`:
|
||||
- for elements it means the same as `tagName`.
|
||||
- for other node types (text, comment etc) it has a string with the node type.
|
||||
- for other node types (text, comment, etc.) it has a string with the node type.
|
||||
|
||||
In other words, `tagName` is only supported by element nodes (as it originates from `Element` class), while `nodeName` can say something about other node types.
|
||||
|
||||
For instance let's compare `tagName` and `nodeName` for the `document` and a comment node:
|
||||
For instance, let's compare `tagName` and `nodeName` for the `document` and a comment node:
|
||||
|
||||
|
||||
```html run
|
||||
|
@ -175,7 +175,7 @@ For instance let's compare `tagName` and `nodeName` for the `document` and a com
|
|||
|
||||
<script>
|
||||
// for comment
|
||||
alert( document.body.firstChild.tagName ); // undefined (not element)
|
||||
alert( document.body.firstChild.tagName ); // undefined (no element)
|
||||
alert( document.body.firstChild.nodeName ); // #comment
|
||||
|
||||
// for document
|
||||
|
@ -218,7 +218,7 @@ The example shows the contents of `document.body` and then replaces it completel
|
|||
</body>
|
||||
```
|
||||
|
||||
We can try to insert an invalid HTML, the browser will fix our errors:
|
||||
We can try to insert invalid HTML, the browser will fix our errors:
|
||||
|
||||
```html run
|
||||
<body>
|
||||
|
@ -461,28 +461,28 @@ Most standard HTML attributes have the corresponding DOM property, and we can ac
|
|||
|
||||
If we want to know the full list of supported properties for a given class, we can find them in the specification. For instance, HTMLInputElement is documented at <https://html.spec.whatwg.org/#htmlinputelement>.
|
||||
|
||||
Or if we'd like to get them fast or interested in the concrete browser -- we can always output the element using `console.dir(elem)` and read the properties. Or explore "DOM properties" in Elements tab of the browser developer tools.
|
||||
Or if we'd like to get them fast or are interested in a concrete browser specification -- we can always output the element using `console.dir(elem)` and read the properties. Or explore "DOM properties" in the Elements tab of the browser developer tools.
|
||||
|
||||
## Summary
|
||||
|
||||
Each DOM node belongs to a certain class. The classes form a hierarchy. The full set of properties and methods comes as the result of inheritance.
|
||||
Each DOM node belongs to a certain class. The classes form a hierarchy. The full set of properties and methods come as the result of inheritance.
|
||||
|
||||
Main DOM node properties are:
|
||||
|
||||
`nodeType`
|
||||
: Node type. We can get it from the DOM object class, but often we need just to see if it is a text or element node. The `nodeType` property is good for that. It has numeric values, most important are: `1` -- for elements,`3` -- for text nodes. Read-only.
|
||||
: We can get `nodeType` from the DOM object class, but often we need just to see if it is a text or element node. The `nodeType` property is good for that. It has numeric values, most important are: `1` -- for elements,`3` -- for text nodes. Read-only.
|
||||
|
||||
`nodeName/tagName`
|
||||
: For elements, tag name (uppercased unless XML-mode). For non-element nodes `nodeName` describes what is it. Read-only.
|
||||
: For elements, tag name (uppercased unless XML-mode). For non-element nodes `nodeName` describes what it is. Read-only.
|
||||
|
||||
`innerHTML`
|
||||
: The HTML content of the element. Can modify.
|
||||
: The HTML content of the element. Can be modified.
|
||||
|
||||
`outerHTML`
|
||||
: The full HTML of the element. A write operation into `elem.outerHTML` does not touch `elem` itself. Instead it gets replaced with the new HTML in the outer context.
|
||||
|
||||
`nodeValue/data`
|
||||
: The content of a non-element node (text, comment). These two are almost the same, usually we use `data`. Can modify.
|
||||
: The content of a non-element node (text, comment). These two are almost the same, usually we use `data`. Can be modified.
|
||||
|
||||
`textContent`
|
||||
: The text inside the element, basically HTML minus all `<tags>`. Writing into it puts the text inside the element, with all special characters and tags treated exactly as text. Can safely insert user-generated text and protect from unwanted HTML insertions.
|
||||
|
@ -490,6 +490,6 @@ Main DOM node properties are:
|
|||
`hidden`
|
||||
: When set to `true`, does the same as CSS `display:none`.
|
||||
|
||||
DOM nodes also have other properties depending on their class. For instance, `<input>` elements (`HTMLInputElement`) support `value`, `type`, while `<a>` elements (`HTMLAnchorElement`) support `href` etc. Most standard HTML attributes have the corresponding DOM property.
|
||||
DOM nodes also have other properties depending on their class. For instance, `<input>` elements (`HTMLInputElement`) support `value`, `type`, while `<a>` elements (`HTMLAnchorElement`) support `href` etc. Most standard HTML attributes have a corresponding DOM property.
|
||||
|
||||
But HTML attributes and DOM properties are not always the same, as we'll see in the next chapter.
|
||||
|
|
|
@ -108,10 +108,10 @@ Here's a demo of reading a non-standard property:
|
|||
</body>
|
||||
```
|
||||
|
||||
HTML attributes have following features:
|
||||
HTML attributes have the following features:
|
||||
|
||||
- Their name is case-insensitive (that's HTML: `id` is same as `ID`).
|
||||
- They are always strings.
|
||||
- Their name is case-insensitive (`id` is same as `ID`).
|
||||
- Their values are always strings.
|
||||
|
||||
Here's an extended demo of working with attributes:
|
||||
|
||||
|
@ -136,7 +136,7 @@ Here's an extended demo of working with attributes:
|
|||
Please note:
|
||||
|
||||
1. `getAttribute('About')` -- the first letter is uppercase here, and in HTML it's all lowercase. But that doesn't matter: attribute names are case-insensitive.
|
||||
2. We can assign anything to an attribute, but that becomes a string. So here we have `"123"` as the value.
|
||||
2. We can assign anything to an attribute, but it becomes a string. So here we have `"123"` as the value.
|
||||
3. All attributes including ones that we set are visible in `outerHTML`.
|
||||
4. The `attributes` collection is iterable and has all attributes with `name` and `value`.
|
||||
|
||||
|
@ -190,7 +190,7 @@ That "feature" may actually come in handy, because the user may modify `value`,
|
|||
|
||||
## DOM properties are typed
|
||||
|
||||
DOM properties are not always strings. For instance, `input.checked` property (for checkboxes) is boolean:
|
||||
DOM properties are not always strings. For instance, the `input.checked` property (for checkboxes) is a boolean:
|
||||
|
||||
```html run
|
||||
<input id="input" type="checkbox" checked> checkbox
|
||||
|
@ -201,7 +201,7 @@ DOM properties are not always strings. For instance, `input.checked` property (f
|
|||
</script>
|
||||
```
|
||||
|
||||
There are other examples. The `style` attribute is a string, but `style` property is an object:
|
||||
There are other examples. The `style` attribute is a string, but the `style` property is an object:
|
||||
|
||||
```html run
|
||||
<div id="div" style="color:red;font-size:120%">Hello</div>
|
||||
|
@ -311,7 +311,7 @@ But there may be a possible problem with custom attributes. What if we use a non
|
|||
|
||||
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.**
|
||||
**All attributes starting with "data-" are reserved for programmers' use. They are available in the `dataset` property.**
|
||||
|
||||
For instance, if an `elem` has an attribute named `"data-about"`, it's available as `elem.dataset.about`.
|
||||
|
||||
|
@ -380,7 +380,7 @@ Methods to work with attributes are:
|
|||
- `elem.removeAttribute(name)` -- to remove the attribute.
|
||||
- `elem.attributes` is a collection of all attributes.
|
||||
|
||||
For most needs DOM properties can serve us well. We should refer to attributes only when DOM properties do not suit us, when we need exactly attributes, for instance:
|
||||
For most needs, DOM properties can serve us well. We should refer to attributes only when DOM properties do not suit us, when we need exactly attributes, for instance:
|
||||
|
||||
- We need a non-standard attribute. But if it starts with `data-`, then we should use `dataset`.
|
||||
- We want to read the value "as written" in HTML. The value of the DOM property may be different, for instance `href` property is always a full URL, and we may want to get the "original" value.
|
||||
- We want to read the value "as written" in HTML. The value of the DOM property may be different, for instance the `href` property is always a full URL, and we may want to get the "original" value.
|
||||
|
|
|
@ -13,4 +13,4 @@ button.addEventListener("click", handler);
|
|||
button.removeEventListener("click", handler);
|
||||
```
|
||||
|
||||
The handler `button.onclick` works independantly and in addition to `addEventListener`.
|
||||
The handler `button.onclick` works independently and in addition to `addEventListener`.
|
||||
|
|
|
@ -26,7 +26,7 @@ If you look closely at these curves, you can immediately notice:
|
|||
|
||||
1. **Points are not always on curve.** That's perfectly normal, later we'll see how the curve is built.
|
||||
2. **The curve order equals the number of points minus one**.
|
||||
For two points we have a linear curve (that's a straight line), for three points -- quadratic curve (parabolic), for three points -- cubic curve.
|
||||
For two points we have a linear curve (that's a straight line), for three points -- quadratic curve (parabolic), for four points -- cubic curve.
|
||||
3. **A curve is always inside the [convex hull](https://en.wikipedia.org/wiki/Convex_hull) of control points:**
|
||||
|
||||
 
|
||||
|
|
|
@ -140,7 +140,7 @@ new Promise(function(resolve, reject) {
|
|||
|
||||
Here the first `.then` shows `1` returns `new Promise(…)` in the line `(*)`. After one second it resolves, and the result (the argument of `resolve`, here it's `result*2`) is passed on to handler of the second `.then` in the line `(**)`. It shows `2` and does the same thing.
|
||||
|
||||
So the output is again 1 -> 2 > 4, but now with 1 second delay between `alert` calls.
|
||||
So the output is again 1 -> 2 -> 4, but now with 1 second delay between `alert` calls.
|
||||
|
||||
Returning promises allows us to build chains of asynchronous actions.
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ Published:
|
|||
In progress:
|
||||
- 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.
|
||||
- Spanish: https://github.com/lmauromb/javascript-tutorial-es
|
||||
- German: https://github.com/MartinEls/javascript-tutorial-de
|
||||
|
||||
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 on your domain.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue