Skip to content

Commit

Permalink
Merge pull request #1 from iliakan/master
Browse files Browse the repository at this point in the history
sync with upsteam
  • Loading branch information
dagolinuxoid authored Sep 28, 2018
2 parents fb99525 + dac2e71 commit 0c4adab
Show file tree
Hide file tree
Showing 54 changed files with 96 additions and 86 deletions.
2 changes: 1 addition & 1 deletion 1-js/01-getting-started/1-intro/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Different engines have different "codenames", for example:

The terms above are good to remember, because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome and Opera.

```smart header="How engines work?"
```smart header="How do engines work?"
Engines are complicated. But the basics are easy.
Expand Down
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/01-hello-world/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The `<script>` tag has a few attributes that are rarely used nowadays, but we ca

The `type` attribute: <code>&lt;script <u>type</u>=...&gt;</code>

: The old standard HTML4 required a script to have a type. Usually it was `type="text/javascript"`. The modern HTML standard assumes this `type` by default. No attribute is required.
: 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 `language` attribute: <code>&lt;script <u>language</u>=...&gt;</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.
Expand All @@ -61,7 +61,7 @@ Comments before and after scripts.
//--></script>
```

These comments were supposed to hide the code from an old browser that didn't know about a `<script>` tag. But all browsers born in the past 15+ years don't have any issues. We mention it here, because such comments serve as a sign. If you see that somewhere -- that code is probably really old and not worth looking into.
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.


## External scripts
Expand Down
2 changes: 1 addition & 1 deletion 1-js/02-first-steps/04-variables/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // error, can't reassign the constant!
```
When a programmer is sure that the variable should never change, he can use `const` to guarantee it, and also to clearly show that fact to everyone.
When a programmer is sure that the variable should never change, they can use `const` to guarantee it, and also to clearly show that fact to everyone.
### Uppercase constants
Expand Down
2 changes: 1 addition & 1 deletion 1-js/02-first-steps/08-comparison/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Yeah, mathematically that's strange. The last result states that "`null` is grea

The reason is that an equality check `==` and comparisons `> < >= <=` work differently. Comparisons convert `null` to a number, hence treat it as `0`. That's why (3) `null >= 0` is true and (1) `null > 0` is false.

On the other hand, the equality check `==` for `undefined` and `null` works by the rule, without any conversions. They equal each other and don't equal anything else. That's why (2) `null == 0` is false.
On the other hand, the equality check `==` for `undefined` and `null` is defined such that, without any conversions, they equal each other and don't equal anything else. That's why (2) `null == 0` is false.

### An incomparable undefined

Expand Down
12 changes: 5 additions & 7 deletions 1-js/02-first-steps/11-logical-operators/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,10 @@ When all values are truthy, the last value is returned:
alert( 1 && 2 && 3 ); // 3, the last one
```
````smart header="AND `&&` executes before OR `||`"
The precedence of the AND `&&` operator is higher than OR `||`, so it executes before OR.
````smart header="Precedence of AND `&&` is higher than OR `||`"
The precedence of AND `&&` operator is higher than OR `||`.
In the code below `1 && 0` is calculated first:
```js run
alert( 5 || 1 && 0 ); // 5
```
So the code `a && b || c && d` is essentially the same as if `&&` were in parentheses: `(a && b) || (c && d)`.
````
Just like OR, the AND `&&` operator can sometimes replace `if`.
Expand Down Expand Up @@ -303,3 +299,5 @@ There's a little more verbose way to do the same thing -- a built-in `Boolean` f
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
```

The precedence of NOT `!` is the highest of all bitwise operators, so it always executes first, before any `&&`, `||`.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ importance: 5

# Repeat until the input is correct

Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask him to input again.
Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask them to input again.

The loop must ask for a number until either the visitor enters a number greater than `100` or cancels the input/enters an empty line.

Expand Down
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/16-javascript-specials/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ More in: <info:variables> and <info:types>.
We're using a browser as a working environment, so basic UI functions will be:

[`prompt(question[, default])`](mdn:api/Window/prompt)
: Ask a `question`, and return either what the visitor entered or `null` if he pressed "cancel".
: Ask a `question`, and return either what the visitor entered or `null` if they pressed "cancel".

[`confirm(question)`](mdn:api/Window/confirm)
: Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`.

[`alert(message)`](mdn:api/Window/alert)
: Output a `message`.

All these functions are *modal*, they pause the code execution and prevent the visitor from interacting with the page until he answers.
All these functions are *modal*, they pause the code execution and prevent the visitor from interacting with the page until they answer.

For instance:

Expand Down
2 changes: 1 addition & 1 deletion 1-js/03-code-quality/03-comments/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Any subtle features of the code? Where they are used?

## Summary

An important sign of a good developer is comments: their presence and even their absense.
An important sign of a good developer is comments: their presence and even their absence.

Good comments allow us to maintain the code well, come back to it after a delay and use it more effectively.

Expand Down
12 changes: 6 additions & 6 deletions 1-js/03-code-quality/04-ninja-code/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0;

Cool, right? If you write like that, the developer who comes across this line and tries to understand what is the value of `i` is going to have a merry time. Then come to you, seeking for an answer.

Tell him that shorter is always better. Initiate him into the paths of ninja.
Tell them that shorter is always better. Initiate them into the paths of ninja.

## One-letter variables

Expand All @@ -45,11 +45,11 @@ completed.

Another way to code faster is to use single-letter variable names everywhere. Like `a`, `b` or `c`.

A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using "search" of the editor. And even if someone does, he won't be able to "decipher" what the name `a` or `b` means.
A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using "search" of the editor. And even if someone does, they won't be able to "decipher" what the name `a` or `b` means.

...But there's an exception. A real ninja will never use `i` as the counter in a `"for"` loop. Anywhere, but not here. Look around, there are many more exotic letters. For instance, `x` or `y`.

An exotic variable as a loop counter is especially cool if the loop body takes 1-2 pages (make it longer if you can). Then if someone looks deep inside the loop, he won't be able to quickly figure out that the variable named `x` is the loop counter.
An exotic variable as a loop counter is especially cool if the loop body takes 1-2 pages (make it longer if you can). Then if someone looks deep inside the loop, they won't be able to quickly figure out that the variable named `x` is the loop counter.

## Use abbreviations

Expand Down Expand Up @@ -153,7 +153,7 @@ function ninjaFunction(elem) {
}
```

A fellow programmer who wants to work with `elem` in the second half of the function will be surprised... Only during the debugging, after examining the code he will find out that he's working with a clone!
A fellow programmer who wants to work with `elem` in the second half of the function will be surprised... Only during the debugging, after examining the code they will find out that he's working with a clone!

Deadly effective even against an experienced ninja. Seen in code regularly.

Expand Down Expand Up @@ -204,7 +204,7 @@ There are functions that look like they don't change anything. Like `isReady()`,

**A really beautiful trick is to add a "useful" action to them, besides the main task.**

The expression of dazed surprise on the face of your colleague when he sees a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.
The expression of dazed surprise on the face of your colleague when they see a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.

**Another way to surprise is to return a non-standard result.**

Expand All @@ -228,7 +228,7 @@ Additional actions should not be obvious from the function name. A true ninja co

**Joining several actions into one protects your code from reuse.**

Imagine, another developer wants only to check the email, and not output any message. Your function `validateEmail(email)` that does both will not suit him. So he won't break your meditation by asking anything about it.
Imagine, another developer wants only to check the email, and not output any message. Your function `validateEmail(email)` that does both will not suit them. So they won't break your meditation by asking anything about it.

## Summary

Expand Down
2 changes: 1 addition & 1 deletion 1-js/03-code-quality/06-polyfills/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Here Babel comes to the rescue.

Actually, there are two parts in Babel:

1. First, the transpiler program, which rewrites the code. The developer runs it on his own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build system like [webpack](http://webpack.github.io/) or [brunch](http://brunch.io/) provide means to run transpiler automatically on every code change, so that doesn't involve any time loss from our side.
1. First, the transpiler program, which rewrites the code. The developer runs it on their own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build system like [webpack](http://webpack.github.io/) or [brunch](http://brunch.io/) provide means to run transpiler automatically on every code change, so that doesn't involve any time loss from our side.

2. Second, the polyfill.

Expand Down
4 changes: 2 additions & 2 deletions 1-js/04-object-basics/01-object/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,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 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 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.
````

Expand Down Expand Up @@ -701,7 +701,7 @@ alert(clone.sizes.width); // 51, see the result from the other one
To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://w3c.github.io/html/infrastructure.html#internal-structured-cloning-algorithm). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](http://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
Expand Down
2 changes: 1 addition & 1 deletion 1-js/04-object-basics/04-object-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ The result of a property access `user.hi` is not a function, but a value of Refe
(user, "hi", true)
```

When parentheses `()` are called on the Reference Type, they receive the full information about the object and it's method, and can set the right `this` (`=user` in this case).
When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`=user` in this case).

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

Expand Down
18 changes: 14 additions & 4 deletions 1-js/04-object-basics/06-constructor-new/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ The constructor can't be called again, because it is not saved anywhere, just cr

## Dual-syntax constructors: new.target

```smart header="Advanced stuff"
The syntax from this section is rarely used, skip it unless you want to know everything.
```

Inside a function, we can check whether it was called with `new` or without it, using a special `new.target` property.

It is empty for regular calls and equals the function if called with `new`:
Expand All @@ -94,14 +98,18 @@ function User() {
alert(new.target);
}

// without new:
// without "new":
*!*
User(); // undefined
*/!*

// with new:
// with "new":
*!*
new User(); // function User { ... }
*/!*
```

That can be used to allow both `new` and regular syntax to work the same:
That can be used to allow both `new` and regular calls to work the same. That is, create the same object:

```js run
function User(name) {
Expand All @@ -116,7 +124,9 @@ let john = User("John"); // redirects call to new User
alert(john.name); // John
```

This approach is sometimes used in libraries to make the syntax more flexible. Probably not a good thing to use everywhere though, because omitting `new` makes it a bit less obvious what's going on. With `new` we all know that the new object is being created, that's a good thing.
This approach is sometimes used in libraries to make the syntax more flexible. So that people may call the function with or without `new`, and it still works.

Probably not a good thing to use everywhere though, because omitting `new` makes it a bit less obvious what's going on. With `new` we all know that the new object is being created.

## Return from constructors

Expand Down
2 changes: 1 addition & 1 deletion 1-js/05-data-types/01-primitives-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

JavaScript allows us to work with primitives (strings, numbers etc) as if they were objects.

They also provide methods to call and 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 more clear).

Let's look at the key distinction between primitives and objects.

Expand Down
2 changes: 1 addition & 1 deletion 1-js/05-data-types/02-number/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ Strange! What is it then if not `0.3`?
alert( 0.1 + 0.2 ); // 0.30000000000000004
```

Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into his chart. The order total will be `$0.30000000000000004`. That would surprise anyone.
Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their chart. The order total will be `$0.30000000000000004`. That would surprise anyone.

But why does this happen?

Expand Down
2 changes: 1 addition & 1 deletion 1-js/05-data-types/03-string/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ Let's recap these methods to avoid any confusion:
```smart header="Which one to choose?"
All of them can do the job. Formally, `substr` has a minor drawback: it is described not in the core JavaScript specification, but in Annex B, which covers browser-only features that exist mainly for historical reasons. So, non-browser environments may fail to support it. But in practice it works everywhere.
The author finds himself using `slice` almost all the time.
The author finds themself using `slice` almost all the time.
```

## Comparing strings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The task consists of two parts.

alert( calc.calculate("3 + 7") ); // 10
```
2. Then add the method `addOperator(name, func)` that teaches the calculator a new operation. It takes the operator `name` and the two-argument function `func(a,b)` that implements it.
2. Then add the method `addMethod(name, func)` that teaches the calculator a new operation. It takes the operator `name` and the two-argument function `func(a,b)` that implements it.

For instance, let's add the multiplication `*`, division `/` and power `**`:

Expand Down
2 changes: 1 addition & 1 deletion 1-js/05-data-types/04-array/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ It's rarely used, because square brackets `[]` are shorter. Also there's a trick

If `new Array` is called with a single argument which is a number, then it creates an array *without items, but with the given length*.

Let's see how one can shoot himself in the foot:
Let's see how one can shoot themself in the foot:

```js run
let arr = new Array(2); // will it create an array of [2] ?
Expand Down
2 changes: 1 addition & 1 deletion 1-js/05-data-types/05-array-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ alert(arr); // *!*1, 2, 15*/!*
````

````smart header="Arrow functions for the best"
Remember [arrow functions](info:function-expression#arrow-functions)? We can use them here for neater sorting:
Remember [arrow functions](info:function-expressions-arrows#arrow-functions)? We can use them here for neater sorting:
```js
arr.sort( (a, b) => a - b );
Expand Down
4 changes: 2 additions & 2 deletions 1-js/05-data-types/07-map-set-weakmap-weakset/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ For instance:
```js run
let john = { name: "John" };

// for every user, let's store his visits count
// for every user, let's store their visits count
let visitsCountMap = new Map();

// john is the key for the map
Expand Down Expand Up @@ -332,7 +332,7 @@ That's useful for situations when we have a main storage for the objects somewhe
Let's look at an example.
For instance, we have code that keeps a visit count for each user. The information is stored in a map: a user is the key and the visit count is the value. When a user leaves, we don't want to store his visit count anymore.
For instance, we have code that keeps a visit count for each user. The information is stored in a map: a user is the key and the visit count is the value. When a user leaves, we don't want to store their visit count anymore.
One way would be to keep track of leaving users and clean up the storage manually:
Expand Down
2 changes: 1 addition & 1 deletion 1-js/06-advanced-functions/03-closure/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ The execution flow of the code above:

1. The global Lexical Environment has `name: "John"`.
2. At the line `(*)` the global variable is changed, now it has `name: "Pete"`.
3. When the function `say()`, is executed and takes `name` from outside. Here that's from the global Lexical Environment where it's already `"Pete"`.
3. When the function `sayHi()`, is executed and takes `name` from outside. Here that's from the global Lexical Environment where it's already `"Pete"`.


```smart header="One call -- one Lexical Environment"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified 1-js/06-advanced-functions/03-closure/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ We do a part of the job `(*)`:
2. Second run: `i=1000001..2000000`.
3. ...and so on, the `while` checks if `i` is evenly divided by `1000000`.

Then the next call is scheduled in `(*)` if we're not done yet.
Then the next call is scheduled in `(**)` if we're not done yet.

Pauses between `count` executions provide just enough "breath" for the JavaScript engine to do something else, to react to other user actions.

Expand Down
Loading

0 comments on commit 0c4adab

Please sign in to comment.