Merge branch 'master' into master
This commit is contained in:
commit
dafb17a168
32 changed files with 114 additions and 123 deletions
|
@ -45,7 +45,7 @@ The engine applies optimizations on every stage of the process. It even watches
|
||||||
|
|
||||||
The modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or CPU, because it was initially created for browsers which do not require it.
|
The modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or CPU, because it was initially created for browsers which do not require it.
|
||||||
|
|
||||||
The capabilities greatly depend on the environment that runs JavaScript. For instance, [Node.JS](https://wikipedia.org/wiki/Node.js) supports functions that allow JavaScript to read/write arbitrary files, perform network requests etc.
|
The capabilities greatly depend on the environment that runs JavaScript. For instance, [Node.JS](https://wikipedia.org/wiki/Node.js) supports functions that allow JavaScript to read/write arbitrary files, perform network requests, etc.
|
||||||
|
|
||||||
In-browser JavaScript can do everything related to webpage manipulation, interaction with the user, and the webserver.
|
In-browser JavaScript can do everything related to webpage manipulation, interaction with the user, and the webserver.
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,12 @@ If you haven't considered selecting an IDE yet, look at the following variants:
|
||||||
- [Visual Studio Code](https://code.visualstudio.com/) (free).
|
- [Visual Studio Code](https://code.visualstudio.com/) (free).
|
||||||
- [Netbeans](http://netbeans.org/) (paid).
|
- [Netbeans](http://netbeans.org/) (paid).
|
||||||
|
|
||||||
All of the IDEs except cross-platform.
|
All of the IDEs are cross-platform.
|
||||||
|
|
||||||
For Windows, there's also a "Visual Studio" editor, don't mess it with "Visual Studio Code". "Visual Studio" is a paid and actually very powerful Windows-only editor, well-suited for .NET platform. A free version of it is called ([Visual Studio Community](https://www.visualstudio.com/vs/community/)).
|
For Windows, there's also a "Visual Studio" editor, don't confuse it with "Visual Studio Code". "Visual Studio" is a paid and actually very powerful Windows-only editor, well-suited for .NET platform. A free version of it is called ([Visual Studio Community](https://www.visualstudio.com/vs/community/).
|
||||||
|
|
||||||
Many IDEs are paid, but have a trial period. Their cost is usually negligible compared to a qualified developer's salary, so just choose the best one for you.
|
Many IDEs are paid, but have a trial period. Their cost is usually negligible compared to a qualified developer's salary, so just choose the best one for you.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Lightweight editors
|
## Lightweight editors
|
||||||
|
|
||||||
"Lightweight editors" are not as powerful as IDEs, but they're fast, elegant and simple.
|
"Lightweight editors" are not as powerful as IDEs, but they're fast, elegant and simple.
|
||||||
|
@ -53,7 +51,7 @@ I'm using:
|
||||||
|
|
||||||
## Let's not argue
|
## Let's not argue
|
||||||
|
|
||||||
The editors in the lists above are those that either I or my friends who I consider good developers have been using for a long time and are happy with.
|
The editors in the lists above are those that either I or my friends whom I consider good developers have been using for a long time and are happy with.
|
||||||
|
|
||||||
There are other great editors in our big world. Please choose the one you like the most.
|
There are other great editors in our big world. Please choose the one you like the most.
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,10 @@ The `<script>` tag has a few attributes that are rarely used nowadays, but we ca
|
||||||
|
|
||||||
The `type` attribute: <code><script <u>type</u>=...></code>
|
The `type` attribute: <code><script <u>type</u>=...></code>
|
||||||
|
|
||||||
: The old standard HTML4 required a script to have a type. Usually it was `type="text/javascript"`. It's not required any more. Also, the modern standard totally changed the meaning of this attribute. Now it can be used for Javascript modules. But that's an advanced topic, but we'll talk about modules later in another part of the tutorial.
|
: The old standard HTML4 required a script to have a type. Usually it was `type="text/javascript"`. It's not required any more. Also, the modern standard totally changed the meaning of this attribute. Now it can be used for Javascript modules. But that's an advanced topic; we'll talk about modules later in another part of the tutorial.
|
||||||
|
|
||||||
The `language` attribute: <code><script <u>language</u>=...></code>
|
The `language` attribute: <code><script <u>language</u>=...></code>
|
||||||
: This attribute was meant to show the language of the script. As of now, this attribute makes no sense, the language is JavaScript by default. No need to use it.
|
: This attribute was meant to show the language of the script. This attribute no longer makes sense, because JavaScript is the default language. No need to use it.
|
||||||
|
|
||||||
Comments before and after scripts.
|
Comments before and after scripts.
|
||||||
: In really ancient books and guides, one may find comments inside `<script>`, like this:
|
: In really ancient books and guides, one may find comments inside `<script>`, like this:
|
||||||
|
@ -61,7 +61,7 @@ Comments before and after scripts.
|
||||||
//--></script>
|
//--></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
This trick isn't used in modern JavaScript. These comments were used to hide the JavaScript code from old browsers that didn't know about a `<script>` tag. Since browsers born in the last 15 years don't have this issue, this kind of comment can help you identify really old code.
|
This trick isn't used in modern JavaScript. These comments were used to hide the JavaScript code from old browsers that didn't know about a `<script>` tag. Since browsers released in the last 15 years don't have this issue, this kind of comment can help you identify really old code.
|
||||||
|
|
||||||
|
|
||||||
## External scripts
|
## External scripts
|
||||||
|
@ -78,7 +78,7 @@ Here `/path/to/script.js` is an absolute path to the file with the script (from
|
||||||
|
|
||||||
It is also possible to provide a path relative to the current page. For instance, `src="script.js"` would mean a file `"script.js"` in the current folder.
|
It is also possible to provide a path relative to the current page. For instance, `src="script.js"` would mean a file `"script.js"` in the current folder.
|
||||||
|
|
||||||
We can give a full URL as well, for instance:
|
We can give a full URL as well. For instance:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"></script>
|
||||||
|
|
|
@ -6,7 +6,7 @@ The first thing to study is the building blocks of the code.
|
||||||
|
|
||||||
Statements are syntax constructs and commands that perform actions.
|
Statements are syntax constructs and commands that perform actions.
|
||||||
|
|
||||||
We've already seen a statement `alert('Hello, world!')`, which shows the message.
|
We've already seen a statement `alert('Hello, world!')`, which shows the message "Hello world!".
|
||||||
|
|
||||||
We can have as many statements in the code as we want. Another statement can be separated with a semicolon.
|
We can have as many statements in the code as we want. Another statement can be separated with a semicolon.
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ alert(3 +
|
||||||
+ 2);
|
+ 2);
|
||||||
```
|
```
|
||||||
|
|
||||||
The code outputs `6`, because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", no semicolon required. And in this case that works as intended.
|
The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so the semicolon is not required. And in this case that works as intended.
|
||||||
|
|
||||||
**But there are situations where JavaScript "fails" to assume a semicolon where it is really needed.**
|
**But there are situations where JavaScript "fails" to assume a semicolon where it is really needed.**
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ It's recommended to put semicolons between statements even if they are separated
|
||||||
|
|
||||||
As time goes on, the program becomes more and more complex. It becomes necessary to add *comments* which describe what happens and why.
|
As time goes on, the program becomes more and more complex. It becomes necessary to add *comments* which describe what happens and why.
|
||||||
|
|
||||||
Comments can be put into any place of the script. They don't affect the execution, because the engine simply ignores them.
|
Comments can be put into any place of the script. They don't affect the execution because the engine simply ignores them.
|
||||||
|
|
||||||
**One-line comments start with two forward slash characters `//`.**
|
**One-line comments start with two forward slash characters `//`.**
|
||||||
|
|
||||||
|
@ -156,4 +156,4 @@ Please, don't hesitate to comment your code.
|
||||||
|
|
||||||
Comments increase the overall code footprint, but that's not a problem at all. There are many tools which minify the code before publishing to the production server. They remove comments, so they don't appear in the working scripts. Therefore comments do not have any negative effects on production at all.
|
Comments increase the overall code footprint, but that's not a problem at all. There are many tools which minify the code before publishing to the production server. They remove comments, so they don't appear in the working scripts. Therefore comments do not have any negative effects on production at all.
|
||||||
|
|
||||||
Further in the tutorial, there will be a chapter <info:coding-style> that also explains how to write better comments.
|
Further in the tutorial there will be a chapter <info:coding-style> that also explains how to write better comments.
|
||||||
|
|
|
@ -263,7 +263,7 @@ function checkAge(age) {
|
||||||
*/!*
|
*/!*
|
||||||
} else {
|
} else {
|
||||||
*!*
|
*!*
|
||||||
return confirm('Got a permission from the parents?');
|
return confirm('Do you have permission from your parents?');
|
||||||
*/!*
|
*/!*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ So, it effectively becomes an empty return. We should put the value on the same
|
||||||
|
|
||||||
## Naming a function [#function-naming]
|
## Naming a function [#function-naming]
|
||||||
|
|
||||||
Functions are actions. So their name is usually a verb. It should briefly, but as accurately as possible describe what the function does. So that a person who reads the code gets the right clue.
|
Functions are actions. So their name is usually a verb. It should briefly, but as accurately as possible, describe what the function does, so that someone reading the code gets an indication of what the function does.
|
||||||
|
|
||||||
It is a widespread practice to start a function with a verbal prefix which vaguely describes the action. There must be an agreement within the team on the meaning of the prefixes.
|
It is a widespread practice to start a function with a verbal prefix which vaguely describes the action. There must be an agreement within the team on the meaning of the prefixes.
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,8 @@ let func = sayHi;
|
||||||
Everything would work the same. Even more obvious what's going on, right?
|
Everything would work the same. Even more obvious what's going on, right?
|
||||||
|
|
||||||
|
|
||||||
````smart header="Why there's a semicolon at the end?"
|
````smart header="Why is there a semicolon at the end?"
|
||||||
There might be a question, why does Function Expression have a semicolon `;` at the end, and Function Declaration does not:
|
You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function sayHi() {
|
function sayHi() {
|
||||||
|
@ -198,7 +198,7 @@ The more subtle difference is *when* a function is created by the JavaScript eng
|
||||||
|
|
||||||
**A Function Expression is created when the execution reaches it and is usable from then on.**
|
**A Function Expression is created when the execution reaches it and is usable from then on.**
|
||||||
|
|
||||||
Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called etc) from now on.
|
Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on.
|
||||||
|
|
||||||
Function Declarations are different.
|
Function Declarations are different.
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ welcome(); // ok now
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```smart header="When to choose Function Declaration versus Function Expression?"
|
```smart header="When should you choose Function Declaration versus Function Expression?"
|
||||||
As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax, the one we used before. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
|
As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax, the one we used before. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
|
||||||
|
|
||||||
It's also a little bit easier to look up `function f(…) {…}` in the code than `let f = function(…) {…}`. Function Declarations are more "eye-catching".
|
It's also a little bit easier to look up `function f(…) {…}` in the code than `let f = function(…) {…}`. Function Declarations are more "eye-catching".
|
||||||
|
@ -375,7 +375,7 @@ In other words, it's roughly the same as:
|
||||||
```js
|
```js
|
||||||
let func = function(arg1, arg2, ...argN) {
|
let func = function(arg1, arg2, ...argN) {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
...But much more concise.
|
...But much more concise.
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
# Coding style
|
# Coding Style
|
||||||
|
|
||||||
Our code must be as clean and easy to read as possible.
|
Our code must be as clean and easy to read as possible.
|
||||||
|
|
||||||
That is actually an art of programming -- to take a complex task and code it in a way that is both correct and human-readable.
|
That is actually the art of programming -- to take a complex task and code it in a way that is both correct and human-readable.
|
||||||
|
|
||||||
One thing to help is the good code style.
|
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
A cheatsheet with the rules (more details below):
|
Here is a cheatsheet with some suggested rules (see below for more details):
|
||||||
|
|
||||||

|

|
||||||
<!--
|
<!--
|
||||||
|
@ -38,13 +36,13 @@ if (n < 0) {
|
||||||
|
|
||||||
Now let's discuss the rules and reasons for them in detail.
|
Now let's discuss the rules and reasons for them in detail.
|
||||||
|
|
||||||
Nothing is "carved in stone" here. Everything is optional and can be changed: these are coding rules, not religious dogmas.
|
```warn header="Irony Detected"
|
||||||
|
Nothing is set in stone here. These are style preferences, not religious dogmas.
|
||||||
|
```
|
||||||
|
|
||||||
### Curly braces
|
### Curly Braces
|
||||||
|
|
||||||
In most JavaScript projects curly braces are written on the same line as the corresponding keyword, not on the new line, a so-called "Egyptian" style. There's also a space before an opening bracket.
|
In most JavaScript projects curly braces are written in "Egyptian" style with the opening brace on the same line as the corresponding keyword -- not on a new line. There should also be a space before the opening bracket, like this:
|
||||||
|
|
||||||
Like this:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
if (condition) {
|
if (condition) {
|
||||||
|
@ -56,7 +54,7 @@ if (condition) {
|
||||||
|
|
||||||
A single-line construct is an important edge case. Should we use brackets at all? If yes, then where?
|
A single-line construct is an important edge case. Should we use brackets at all? If yes, then where?
|
||||||
|
|
||||||
Here are the annotated variants, so you can judge about their readability on your own:
|
Here are the annotated variants so you can judge their readability for yourself:
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
```js no-beautify
|
```js no-beautify
|
||||||
|
@ -74,21 +72,21 @@ if (n < 0) {
|
||||||
-->
|
-->
|
||||||

|

|
||||||
|
|
||||||
As a summary:
|
In summary:
|
||||||
- For a really short code, one line is acceptable: like `if (cond) return null`.
|
- For very short code, one line is acceptable. For example: `if (cond) return null`.
|
||||||
- But a separate line for each statement in brackets is usually better.
|
- But a separate line for each statement in brackets is usually easier to read.
|
||||||
|
|
||||||
### Line length
|
### Line Length
|
||||||
|
|
||||||
The maximal line length should be limited. No one likes to eye-follow a long horizontal line. It's better to split it.
|
No one likes to read a long horizontal line of code. It's best practice to split them up and limit the length of your lines.
|
||||||
|
|
||||||
The maximal line length is agreed on the team-level. It's usually 80 or 120 characters.
|
The maximum line length should be agreed upon at the team-level. It's usually 80 or 120 characters.
|
||||||
|
|
||||||
### Indents
|
### Indents
|
||||||
|
|
||||||
There are two types of indents:
|
There are two types of indents:
|
||||||
|
|
||||||
- **A horizontal indent: 2(4) spaces.**
|
- **Horizontal indents: 2 or 4 spaces.**
|
||||||
|
|
||||||
A horizontal indentation is made using either 2 or 4 spaces or the "Tab" symbol. Which one to choose is an old holy war. Spaces are more common nowadays.
|
A horizontal indentation is made using either 2 or 4 spaces or the "Tab" symbol. Which one to choose is an old holy war. Spaces are more common nowadays.
|
||||||
|
|
||||||
|
@ -107,9 +105,9 @@ There are two types of indents:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **A vertical indent: empty lines for splitting code into logical blocks.**
|
- **Vertical indents: empty lines for splitting code into logical blocks.**
|
||||||
|
|
||||||
Even a single function can often be divided in logical blocks. In the example below, the initialization of variables, the main loop and returning the result are split vertically:
|
Even a single function can often be divided into logical blocks. In the example below, the initialization of variables, the main loop and returning the result are split vertically:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function pow(x, n) {
|
function pow(x, n) {
|
||||||
|
@ -125,21 +123,21 @@ There are two types of indents:
|
||||||
|
|
||||||
Insert an extra newline where it helps to make the code more readable. There should not be more than nine lines of code without a vertical indentation.
|
Insert an extra newline where it helps to make the code more readable. There should not be more than nine lines of code without a vertical indentation.
|
||||||
|
|
||||||
### A semicolon
|
### Semicolons
|
||||||
|
|
||||||
A semicolon should be present after each statement. Even if it could possibly be skipped.
|
A semicolon should be present after each statement, even if it could possibly be skipped.
|
||||||
|
|
||||||
There are languages where a semicolon is truly optional. It's rarely used there. But in JavaScript there are few cases when a line break is sometimes not interpreted as a semicolon. That leaves a place for programming errors.
|
There are languages where a semicolon is truly optional and it is rarely used. In JavaScript, though, there are cases where a line break is not interpreted as a semicolon, leaving the code vulnerable to errors.
|
||||||
|
|
||||||
As you become more mature as a programmer, you may choose a no-semicolon style, like [StandardJS](https://standardjs.com/), but that's only when you know JavaScript well and understand possible pitfalls.
|
As you become more mature as a programmer, you may choose a no-semicolon style like [StandardJS](https://standardjs.com/). Until then, it's best to use semicolons to avoid possible pitfalls.
|
||||||
|
|
||||||
### Nesting levels
|
### Nesting Levels
|
||||||
|
|
||||||
There should not be too many nesting levels.
|
Try to avoid nesting code too many levels deep.
|
||||||
|
|
||||||
Sometimes it's a good idea to use the ["continue"](info:while-for#continue) directive in the loop to evade extra nesting in `if(..) { ... }`:
|
Sometimes it's a good idea to use the ["continue"](info:while-for#continue) directive in a loop to avoid extra nesting.
|
||||||
|
|
||||||
Instead of:
|
For example, instead of adding a nested `if` conditional like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
|
@ -162,7 +160,7 @@ A similar thing can be done with `if/else` and `return`.
|
||||||
|
|
||||||
For example, two constructs below are identical.
|
For example, two constructs below are identical.
|
||||||
|
|
||||||
The first one:
|
Option 1:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function pow(x, n) {
|
function pow(x, n) {
|
||||||
|
@ -180,7 +178,7 @@ function pow(x, n) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
And this:
|
Option 2:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function pow(x, n) {
|
function pow(x, n) {
|
||||||
|
@ -199,13 +197,13 @@ function pow(x, n) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
...But the second one is more readable, because the "edge case" of `n < 0` is handled early on, and then we have the "main" code flow, without an additional nesting.
|
The second one is more readable because the "edge case" of `n < 0` is handled early on. Once the check is done we can move on to the "main" code flow without the need for additional nesting.
|
||||||
|
|
||||||
## Functions below the code
|
## Function Placement
|
||||||
|
|
||||||
If you are writing several "helper" functions and the code to use them, then there are three ways to place them.
|
If you are writing several "helper" functions and the code that uses them, there are three ways to organize the functions.
|
||||||
|
|
||||||
1. Functions above the code that uses them:
|
1. Functions declared above the code that uses them:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// *!*function declarations*/!*
|
// *!*function declarations*/!*
|
||||||
|
@ -235,7 +233,6 @@ If you are writing several "helper" functions and the code to use them, then the
|
||||||
walkAround();
|
walkAround();
|
||||||
|
|
||||||
// --- *!*helper functions*/!* ---
|
// --- *!*helper functions*/!* ---
|
||||||
|
|
||||||
function createElement() {
|
function createElement() {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
@ -248,39 +245,37 @@ If you are writing several "helper" functions and the code to use them, then the
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
3. Mixed: a function is described where it's first used.
|
3. Mixed: a function is declared where it's first used.
|
||||||
|
|
||||||
Most of time, the second variant is preferred.
|
Most of time, the second variant is preferred.
|
||||||
|
|
||||||
That's because when reading a code, we first want to know "what it does". If the code goes first, then it provides that information. And then maybe we won't need to read functions at all, especially if their names are adequate to what they're doing.
|
That's because when reading code, we first want to know *what it does*. If the code goes first, then it provides that information. Then, maybe we won't need to read the functions at all, especially if their names are descriptive of what they actually do.
|
||||||
|
|
||||||
## Style guides
|
## Style Guides
|
||||||
|
|
||||||
A style guide contains general rules about "how to write": which quotes to use, how many spaces to indent, where to put line breaks, etc. A lot of minor things.
|
A style guide contains general rules about "how to write" code, e.g. which quotes to use, how many spaces to indent, where to put line breaks, etc. A lot of minor things.
|
||||||
|
|
||||||
In total, when all members of a team use the same style guide, the code looks uniform. No matter who of the team wrote it, it's still the same style.
|
When all members of a team use the same style guide the code tends looks uniform, regardless of which team member wrote it.
|
||||||
|
|
||||||
Surely, a team may think out a style guide themselves. But as of now, there's no need to. There are many tried, worked-out style guides, which are easy to adopt.
|
Of course, a team can always write their own style guide. Most of the time though, there's no need to. There are many existing tried and true options to choose from, so adopting one of these is usually your best bet.
|
||||||
|
|
||||||
For instance:
|
Some popular choices:
|
||||||
|
|
||||||
- [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
|
- [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
|
||||||
- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
|
- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
|
||||||
- [Idiomatic.JS](https://github.com/rwaldron/idiomatic.js)
|
- [Idiomatic.JS](https://github.com/rwaldron/idiomatic.js)
|
||||||
- [StandardJS](https://standardjs.com/)
|
- [StandardJS](https://standardjs.com/)
|
||||||
- (there are more)
|
- (plus many more)
|
||||||
|
|
||||||
If you're a novice developer, then you could start with the cheatsheet above in the chapter, and later browse the style guides to pick up the common principles and maybe choose one.
|
If you're a novice developer, start with the cheatsheet at the beginning of this chapter. Once you've mastered that you can browse other style guides to pick up common principles and decide which one you like best.
|
||||||
|
|
||||||
## Automated linters
|
## Automated Linters
|
||||||
|
|
||||||
There are tools that can check the code style automatically. They are called "linters".
|
Linters are tools that can automatically check the style of your code and make suggestions for refactoring.
|
||||||
|
|
||||||
The great thing about them is that style-checking also finds some bugs, like a typo in a variable or function name.
|
The great thing about them is that style-checking can also find some bugs, like typos in variable or function names. Because of this feature, installing a linter is recommended even if you don't want to stick to one particular "code style".
|
||||||
|
|
||||||
So it's recommended to install one, even if you don't want to stick to a "code style". They help to find typos -- and that's already good enough.
|
Here are the most well-known linting tools:
|
||||||
|
|
||||||
Most well-known tools are:
|
|
||||||
|
|
||||||
- [JSLint](http://www.jslint.com/) -- one of the first linters.
|
- [JSLint](http://www.jslint.com/) -- one of the first linters.
|
||||||
- [JSHint](http://www.jshint.com/) -- more settings than JSLint.
|
- [JSHint](http://www.jshint.com/) -- more settings than JSLint.
|
||||||
|
@ -288,15 +283,16 @@ Most well-known tools are:
|
||||||
|
|
||||||
All of them can do the job. The author uses [ESLint](http://eslint.org/).
|
All of them can do the job. The author uses [ESLint](http://eslint.org/).
|
||||||
|
|
||||||
Most linters are integrated with editors: just enable the plugin in the editor and configure the style.
|
Most linters are integrated with many popular editors: just enable the plugin in the editor and configure the style.
|
||||||
|
|
||||||
For instance, for ESLint you should do the following:
|
For instance, for ESLint you should do the following:
|
||||||
|
|
||||||
1. Install [Node.JS](https://nodejs.org/).
|
1. Install [Node.JS](https://nodejs.org/).
|
||||||
2. Install ESLint with the command `npm install -g eslint` (npm is a JavaScript package installer).
|
2. Install ESLint with the command `npm install -g eslint` (npm is a JavaScript package installer).
|
||||||
3. Create a config file named `.eslintrc` in the root of your JavaScript project (in the folder that contains all your files).
|
3. Create a config file named `.eslintrc` in the root of your JavaScript project (in the folder that contains all your files).
|
||||||
|
4. Install/enable the plugin for your editor that integrates with ESLint. The majority of editors have one.
|
||||||
|
|
||||||
Here's an example of `.eslintrc`:
|
Here's an example of an `.eslintrc` file:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
|
@ -313,22 +309,16 @@ Here's an example of `.eslintrc`:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here the directive `"extends"` denotes that we base on the "eslint:recommended" set of settings, and then we specify our own.
|
Here the directive `"extends"` denotes that the configuration is based on the "eslint:recommended" set of settings. After that, we specify our own.
|
||||||
|
|
||||||
Then install/enable the plugin for your editor that integrates with ESLint. The majority of editors have it.
|
It is also possible to download style rule sets from the web and extend them instead. See <http://eslint.org/docs/user-guide/getting-started> for more details about installation.
|
||||||
|
|
||||||
It is possible to download style rule sets from the web and extend them instead. See <http://eslint.org/docs/user-guide/getting-started> for more details about installation.
|
Also certain IDEs have built-in linting, which is convenient but not as customizable as ESLint.
|
||||||
|
|
||||||
Using a linter has a great side-effect: linters catch typos. For instance, when an undefined variable is accessed, a linter detects it and (if integrated with an editor) highlights it. In most cases that's a mistype. So we can fix it right ahead.
|
|
||||||
|
|
||||||
For that reason even if you're not concerned about styles, using a linter is highly recommended.
|
|
||||||
|
|
||||||
Also certain IDEs support built-in linting, that also may be good, but not so tunable as ESLint.
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
All syntax rules from this chapter and the style guides aim to increase readability, so all of them are debatable.
|
All syntax rules described in this chapter (and in the style guides referenced) aim to increase the readability of your code, but all of them are debatable.
|
||||||
|
|
||||||
When we think about "how to write better?", the sole criterion is "what makes the code more readable and easier to understand? what helps to avoid errors?" That's the main thing to keep in mind when choosing the style or discussing which one is better.
|
When we think about writing "better" code, the questions we should ask are, "What makes the code more readable and easier to understand?" and "What can help us avoid errors?" These are the main things to keep in mind when choosing and debating code styles.
|
||||||
|
|
||||||
Read style guides to see the latest ideas about that and follow those that you find the best.
|
Reading popular style guides will allow you to keep up to date with the latest ideas about code style trends and best practices.
|
||||||
|
|
|
@ -96,7 +96,7 @@ The full HTML page with these frameworks and `pow` spec:
|
||||||
```html src="index.html"
|
```html src="index.html"
|
||||||
```
|
```
|
||||||
|
|
||||||
The page can be divided into four parts:
|
The page can be divided into five parts:
|
||||||
|
|
||||||
1. The `<head>` -- add third-party libraries and styles for tests.
|
1. The `<head>` -- add third-party libraries and styles for tests.
|
||||||
2. The `<script>` with the function to test, in our case -- with the code for `pow`.
|
2. The `<script>` with the function to test, in our case -- with the code for `pow`.
|
||||||
|
|
|
@ -4,7 +4,7 @@ importance: 5
|
||||||
|
|
||||||
# Constant objects?
|
# Constant objects?
|
||||||
|
|
||||||
Is it possible to change an object declared with `const`, how do you think?
|
Is it possible to change an object declared with `const`? What do you think?
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const user = {
|
const user = {
|
||||||
|
|
|
@ -205,7 +205,7 @@ let obj = {
|
||||||
for: 1,
|
for: 1,
|
||||||
let: 2,
|
let: 2,
|
||||||
return: 3
|
return: 3
|
||||||
}
|
};
|
||||||
|
|
||||||
alert( obj.for + obj.let + obj.return ); // 6
|
alert( obj.for + obj.let + obj.return ); // 6
|
||||||
```
|
```
|
||||||
|
@ -605,7 +605,7 @@ for (let key in user) {
|
||||||
}
|
}
|
||||||
*/!*
|
*/!*
|
||||||
|
|
||||||
// now clone is a fully independant clone
|
// now clone is a fully independent clone
|
||||||
clone.name = "Pete"; // changed the data in it
|
clone.name = "Pete"; // changed the data in it
|
||||||
|
|
||||||
alert( user.name ); // still John in the original object
|
alert( user.name ); // still John in the original object
|
||||||
|
|
|
@ -75,7 +75,7 @@ user[id] = "ID Value";
|
||||||
alert( user[id] ); // we can access the data using the symbol as the key
|
alert( user[id] ); // we can access the data using the symbol as the key
|
||||||
```
|
```
|
||||||
|
|
||||||
What's the benefit over using `Symbol("id")` over a string `"id"`?
|
What's the benefit of using `Symbol("id")` over a string `"id"`?
|
||||||
|
|
||||||
Let's make the example a bit deeper to see that.
|
Let's make the example a bit deeper to see that.
|
||||||
|
|
||||||
|
|
|
@ -316,7 +316,7 @@ When parentheses `()` are called on the Reference Type, they receive the full in
|
||||||
|
|
||||||
Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`.
|
Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`.
|
||||||
|
|
||||||
So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj[method]()` syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind).
|
So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind).
|
||||||
|
|
||||||
## Arrow functions have no "this"
|
## Arrow functions have no "this"
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
# Methods of primitives
|
# Methods of primitives
|
||||||
|
|
||||||
JavaScript allows us to work with primitives (strings, numbers etc) as if they were objects.
|
JavaScript allows us to work with primitives (strings, numbers, etc.) as if they were objects.
|
||||||
|
|
||||||
They also provide methods to call as such. We will study those soon, but first we'll see how it works, because, of course, primitives are not objects (and here we will make it even more clear).
|
They also provide methods to call as such. We will study those soon, but first we'll see how it works because, of course, primitives are not objects (and here we will make it even clearer).
|
||||||
|
|
||||||
Let's look at the key distinction between primitives and objects.
|
Let's look at the key distinctions between primitives and objects.
|
||||||
|
|
||||||
A primitive
|
A primitive
|
||||||
: Is a value of a primitive type. There are 6 primitive types: `string`, `number`, `boolean`, `symbol`, `null` and `undefined`.
|
|
||||||
|
- Is a value of a primitive type.
|
||||||
|
- There are 6 primitive types: `string`, `number`, `boolean`, `symbol`, `null` and `undefined`.
|
||||||
|
|
||||||
An object
|
An object
|
||||||
: Is capable of storing multiple values as properties.
|
|
||||||
Can be created with `{}`, for instance: `{name: "John", age: 30}`. There are other kinds of objects in JavaScript, e.g. functions are objects.
|
|
||||||
|
|
||||||
One of the best things about objects is that we can store a function as one of its properties:
|
- Is capable of storing multiple values as properties.
|
||||||
|
- Can be created with `{}`, for instance: `{name: "John", age: 30}`. There are other kinds of objects in JavaScript; functions, for example, are objects.
|
||||||
|
|
||||||
|
One of the best things about objects is that we can store a function as one of its properties.
|
||||||
|
|
||||||
```js run
|
```js run
|
||||||
let john = {
|
let john = {
|
||||||
|
@ -28,7 +31,7 @@ john.sayHi(); // Hi buddy!
|
||||||
|
|
||||||
So here we've made an object `john` with the method `sayHi`.
|
So here we've made an object `john` with the method `sayHi`.
|
||||||
|
|
||||||
Many built-in objects already exist, such as those that work with dates, errors, HTML elements etc. They have different properties and methods.
|
Many built-in objects already exist, such as those that work with dates, errors, HTML elements, etc. They have different properties and methods.
|
||||||
|
|
||||||
But, these features come with a cost!
|
But, these features come with a cost!
|
||||||
|
|
||||||
|
|
|
@ -349,7 +349,7 @@ But in real life we often have values in units, like `"100px"` or `"12pt"` in CS
|
||||||
|
|
||||||
That's what `parseInt` and `parseFloat` are for.
|
That's what `parseInt` and `parseFloat` are for.
|
||||||
|
|
||||||
They "read" a number from a string until they can. In case of an error, the gathered number is returned. The function `parseInt` returns an integer, whilst `parseFloat` will return a floating-point number:
|
They "read" a number from a string until they can't. In case of an error, the gathered number is returned. The function `parseInt` returns an integer, whilst `parseFloat` will return a floating-point number:
|
||||||
|
|
||||||
```js run
|
```js run
|
||||||
alert( parseInt('100px') ); // 100
|
alert( parseInt('100px') ); // 100
|
||||||
|
|
|
@ -324,7 +324,7 @@ Now where do we need such thing?
|
||||||
The idea of `WeakMap` is that we can store something for an object that exists only while the object exists. But we do not force the object to live by the mere fact that we store something for it.
|
The idea of `WeakMap` is that we can store something for an object that exists only while the object exists. But we do not force the object to live by the mere fact that we store something for it.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
weakMap.put(john, "secret documents");
|
weakMap.set(john, "secret documents");
|
||||||
// if john dies, secret documents will be destroyed
|
// if john dies, secret documents will be destroyed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ With a regular `Map`, cleaning up after a user has left becomes a tedious task:
|
||||||
`WeakSet` behaves similarly:
|
`WeakSet` behaves similarly:
|
||||||
|
|
||||||
- It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives).
|
- It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives).
|
||||||
- An object exists in the set while it has reachable from somewhere else.
|
- An object exists in the set while it is reachable from somewhere else.
|
||||||
- Like `Set`, it supports `add`, `has` and `delete`, but not `size`, `keys()` and no iterations.
|
- Like `Set`, it supports `add`, `has` and `delete`, but not `size`, `keys()` and no iterations.
|
||||||
|
|
||||||
For instance, we can use it to keep track of whether an item is checked:
|
For instance, we can use it to keep track of whether an item is checked:
|
||||||
|
@ -429,4 +429,4 @@ The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterati
|
||||||
|
|
||||||
- Also does not support `size/clear()` and iterations.
|
- Also does not support `size/clear()` and iterations.
|
||||||
|
|
||||||
`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "main" object storage. Once the object is removed from the main storage, so it only stays in `WeakMap/WeakSet`, they clean up automatically.
|
`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "main" object storage. Once the object is removed from the main storage, if it is only found in the `WeakMap/WeakSet`, it will be cleaned up automatically.
|
||||||
|
|
|
@ -9,7 +9,7 @@ Clock.prototype._render = function() {
|
||||||
if (hours < 10) hours = '0' + hours;
|
if (hours < 10) hours = '0' + hours;
|
||||||
|
|
||||||
let mins = date.getMinutes();
|
let mins = date.getMinutes();
|
||||||
if (mins < 10) min = '0' + mins;
|
if (mins < 10) mins = '0' + mins;
|
||||||
|
|
||||||
let secs = date.getSeconds();
|
let secs = date.getSeconds();
|
||||||
if (secs < 10) secs = '0' + secs;
|
if (secs < 10) secs = '0' + secs;
|
||||||
|
|
|
@ -9,7 +9,7 @@ function Clock({ template }) {
|
||||||
if (hours < 10) hours = '0' + hours;
|
if (hours < 10) hours = '0' + hours;
|
||||||
|
|
||||||
let mins = date.getMinutes();
|
let mins = date.getMinutes();
|
||||||
if (mins < 10) min = '0' + mins;
|
if (mins < 10) mins = '0' + mins;
|
||||||
|
|
||||||
let secs = date.getSeconds();
|
let secs = date.getSeconds();
|
||||||
if (secs < 10) secs = '0' + secs;
|
if (secs < 10) secs = '0' + secs;
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Clock {
|
||||||
if (hours < 10) hours = '0' + hours;
|
if (hours < 10) hours = '0' + hours;
|
||||||
|
|
||||||
let mins = date.getMinutes();
|
let mins = date.getMinutes();
|
||||||
if (mins < 10) min = '0' + mins;
|
if (mins < 10) mins = '0' + mins;
|
||||||
|
|
||||||
let secs = date.getSeconds();
|
let secs = date.getSeconds();
|
||||||
if (secs < 10) secs = '0' + secs;
|
if (secs < 10) secs = '0' + secs;
|
||||||
|
|
|
@ -11,7 +11,7 @@ Clock.prototype._render = function() {
|
||||||
if (hours < 10) hours = '0' + hours;
|
if (hours < 10) hours = '0' + hours;
|
||||||
|
|
||||||
let mins = date.getMinutes();
|
let mins = date.getMinutes();
|
||||||
if (mins < 10) min = '0' + mins;
|
if (mins < 10) mins = '0' + mins;
|
||||||
|
|
||||||
let secs = date.getSeconds();
|
let secs = date.getSeconds();
|
||||||
if (secs < 10) secs = '0' + secs;
|
if (secs < 10) secs = '0' + secs;
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Clock {
|
||||||
if (hours < 10) hours = '0' + hours;
|
if (hours < 10) hours = '0' + hours;
|
||||||
|
|
||||||
let mins = date.getMinutes();
|
let mins = date.getMinutes();
|
||||||
if (mins < 10) min = '0' + mins;
|
if (mins < 10) mins = '0' + mins;
|
||||||
|
|
||||||
let secs = date.getSeconds();
|
let secs = date.getSeconds();
|
||||||
if (secs < 10) secs = '0' + secs;
|
if (secs < 10) secs = '0' + secs;
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Clock {
|
||||||
if (hours < 10) hours = '0' + hours;
|
if (hours < 10) hours = '0' + hours;
|
||||||
|
|
||||||
let mins = date.getMinutes();
|
let mins = date.getMinutes();
|
||||||
if (mins < 10) min = '0' + mins;
|
if (mins < 10) mins = '0' + mins;
|
||||||
|
|
||||||
let secs = date.getSeconds();
|
let secs = date.getSeconds();
|
||||||
if (secs < 10) secs = '0' + secs;
|
if (secs < 10) secs = '0' + secs;
|
||||||
|
|
|
@ -255,7 +255,7 @@ The syntax is:
|
||||||
throw <error object>
|
throw <error object>
|
||||||
```
|
```
|
||||||
|
|
||||||
Technically, we can use anything as an error object. That may be even a primitive, like a number or a string, but it's better to use objects, preferrably with `name` and `message` properties (to stay somewhat compatible with built-in errors).
|
Technically, we can use anything as an error object. That may be even a primitive, like a number or a string, but it's better to use objects, preferably with `name` and `message` properties (to stay somewhat compatible with built-in errors).
|
||||||
|
|
||||||
JavaScript has many built-in constructors for standard errors: `Error`, `SyntaxError`, `ReferenceError`, `TypeError` and others. We can use them to create error objects as well.
|
JavaScript has many built-in constructors for standard errors: `Error`, `SyntaxError`, `ReferenceError`, `TypeError` and others. We can use them to create error objects as well.
|
||||||
|
|
||||||
|
|
|
@ -409,7 +409,7 @@ The syntax:
|
||||||
|
|
||||||
The call to `document.write(html)` writes the `html` into page "right here and now". The `html` string can be dynamically generated, so it's kind of flexible. We can use JavaScript to create a full-fledged webpage and write it.
|
The call to `document.write(html)` writes the `html` into page "right here and now". The `html` string can be dynamically generated, so it's kind of flexible. We can use JavaScript to create a full-fledged webpage and write it.
|
||||||
|
|
||||||
The method comes from times when there were no DOM, no standards... Really old times. It still lives, because there are scripts using it.
|
The method comes from times when there was no DOM, no standards... Really old times. It still lives, because there are scripts using it.
|
||||||
|
|
||||||
In modern scripts we can rarely see it, because of the following important limitation:
|
In modern scripts we can rarely see it, because of the following important limitation:
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ These properties are rarely needed, but still they are the "most outer" geometry
|
||||||
|
|
||||||
The `offsetParent` is the nearest ancestor that is:
|
The `offsetParent` is the nearest ancestor that is:
|
||||||
|
|
||||||
1. CSS-positioned (`position` is `absolute`, `relative` or `fixed`),
|
1. CSS-positioned (`position` is `absolute`, `relative`, `fixed` or `sticky`),
|
||||||
2. or `<td>`, `<th>`, `<table>`,
|
2. or `<td>`, `<th>`, `<table>`,
|
||||||
2. or `<body>`.
|
2. or `<body>`.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ There are two ways to tell the browser we don't want it to act:
|
||||||
- The main way is to use the `event` object. There's a method `event.preventDefault()`.
|
- The main way is to use the `event` object. There's a method `event.preventDefault()`.
|
||||||
- If the handler is assigned using `on<event>` (not by `addEventListener`), then we can just return `false` from it.
|
- If the handler is assigned using `on<event>` (not by `addEventListener`), then we can just return `false` from it.
|
||||||
|
|
||||||
In the example below there a click to links don't lead to URL change:
|
In the example below a click to links doesn't lead to URL change:
|
||||||
|
|
||||||
```html autorun height=60 no-beautify
|
```html autorun height=60 no-beautify
|
||||||
<a href="/" onclick="return false">Click here</a>
|
<a href="/" onclick="return false">Click here</a>
|
||||||
|
|
|
@ -269,7 +269,7 @@ To generate an event, we first need to create an event object.
|
||||||
|
|
||||||
The generic `Event(name, options)` constructor accepts an arbitrary event name and the `options` object with two properties:
|
The generic `Event(name, options)` constructor accepts an arbitrary event name and the `options` object with two properties:
|
||||||
- `bubbles: true` if the event should bubble.
|
- `bubbles: true` if the event should bubble.
|
||||||
- `cancelable: true` is the `event.preventDefault()` should work.
|
- `cancelable: true` if the `event.preventDefault()` should work.
|
||||||
|
|
||||||
Other constructors of native events like `MouseEvent`, `KeyboardEvent` and so on accept properties specific to that event type. For instance, `clientX` for mouse events.
|
Other constructors of native events like `MouseEvent`, `KeyboardEvent` and so on accept properties specific to that event type. For instance, `clientX` for mouse events.
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,6 @@ class HoverIntent {
|
||||||
elem.removeEventListener('mousemove', this.onMouseMove);
|
elem.removeEventListener('mousemove', this.onMouseMove);
|
||||||
elem.removeEventListener('mouseover', this.onMouseOver);
|
elem.removeEventListener('mouseover', this.onMouseOver);
|
||||||
elem.removeEventListener('mouseout', this.onMouseOut);
|
elem.removeEventListener('mouseout', this.onMouseOut);
|
||||||
};
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,6 @@ class HoverIntent {
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
/* your code to "disable" the functionality, remove all handlers */
|
/* your code to "disable" the functionality, remove all handlers */
|
||||||
};
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ Now let's see how some examples. First, about pages that come from the same orig
|
||||||
````warn header="Subdomains may be same-origin"
|
````warn header="Subdomains may be same-origin"
|
||||||
There's a small exclusion in the "Same Origin" policy.
|
There's a small exclusion in the "Same Origin" policy.
|
||||||
|
|
||||||
If windows share the same second-level domain, for instance `john.site.com`, `peter.site.com` and `site.com` (so that theyr common second-level domain is `site.com`), they can be treated as coming from the "same origin".
|
If windows share the same second-level domain, for instance `john.site.com`, `peter.site.com` and `site.com` (so that their common second-level domain is `site.com`), they can be treated as coming from the "same origin".
|
||||||
|
|
||||||
To make it work, all such pages (including the one from `site.com`) should run the code:
|
To make it work, all such pages (including the one from `site.com`) should run the code:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Find color in the format #abc or #abcdef
|
# Find color in the format #abc or #abcdef
|
||||||
|
|
||||||
Write a regexp that matches colors in the format `#abc` or `#abcdef`. That is: `#` followed by 3 or 6 hexadimal digits.
|
Write a RegExp that matches colors in the format `#abc` or `#abcdef`. That is: `#` followed by 3 or 6 hexadecimal digits.
|
||||||
|
|
||||||
Usage example:
|
Usage example:
|
||||||
```js
|
```js
|
||||||
|
@ -11,4 +11,4 @@ let str = "color: #3f3; background-color: #AA00ef; and: #abcd";
|
||||||
alert( str.match(reg) ); // #3f3 #AA0ef
|
alert( str.match(reg) ); // #3f3 #AA0ef
|
||||||
```
|
```
|
||||||
|
|
||||||
P.S. Should be exactly 3 or 6 hex digits: values like `#abcd` should not match.
|
P.S. This should be exactly 3 or 6 hex digits: values like `#abcd` should not match.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Capturing groups
|
# Capturing groups
|
||||||
|
|
||||||
A part of the pattern can be enclosed in parentheses `pattern:(...)`. That's called a "capturing group".
|
A part of a pattern can be enclosed in parentheses `pattern:(...)`. This is called a "capturing group".
|
||||||
|
|
||||||
That has two effects:
|
That has two effects:
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ john.smith@site.com.uk
|
||||||
|
|
||||||
The pattern: `pattern:[-.\w]+@([\w-]+\.)+[\w-]{2,20}`.
|
The pattern: `pattern:[-.\w]+@([\w-]+\.)+[\w-]{2,20}`.
|
||||||
|
|
||||||
- The first part before `@` may include wordly characters, a dot and a dash `pattern:[-.\w]+`, like `match:john.smith`.
|
- The first part before `@` may include any alphanumeric word characters, a dot and a dash `pattern:[-.\w]+`, like `match:john.smith`.
|
||||||
- Then `pattern:@`
|
- Then `pattern:@`
|
||||||
- And then the domain. May be a second-level domain `site.com` or with subdomains like `host.site.com.uk`. We can match it as "a word followed by a dot" repeated one or more times for subdomains: `match:mail.` or `match:site.com.`, and then "a word" for the last part: `match:.com` or `match:.uk`.
|
- And then the domain and maybe a second-level domain like `site.com` or with subdomains like `host.site.com.uk`. We can match it as "a word followed by a dot" repeated one or more times for subdomains: `match:mail.` or `match:site.com.`, and then "a word" for the last part: `match:.com` or `match:.uk`.
|
||||||
|
|
||||||
The word followed by a dot is `pattern:(\w+\.)+` (repeated). The last word should not have a dot at the end, so it's just `\w{2,20}`. The quantifier `pattern:{2,20}` limits the length, because domain zones are like `.uk` or `.com` or `.museum`, but can't be longer than 20 characters.
|
The word followed by a dot is `pattern:(\w+\.)+` (repeated). The last word should not have a dot at the end, so it's just `\w{2,20}`. The quantifier `pattern:{2,20}` limits the length, because domain zones are like `.uk` or `.com` or `.museum`, but can't be longer than 20 characters.
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ The meaning is the same: it ensures that the returned value is a promise and ena
|
||||||
````
|
````
|
||||||
## Error handling
|
## Error handling
|
||||||
|
|
||||||
If a promise resolves normally, then `await promise` returns the result. But in case of a rejection, it throws the error, just if there were a `throw` statement at that line.
|
If a promise resolves normally, then `await promise` returns the result. But in case of a rejection, it throws the error, just as if there were a `throw` statement at that line.
|
||||||
|
|
||||||
This code:
|
This code:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue