Skip to content

Sync with upstream @ 70ca842b #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 79 commits into from
Oct 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
da8af69
Update article.md
hrodward Oct 17, 2019
5b795f7
minor
Darryl1702 Oct 19, 2019
aae1e26
Update article.md
Darryl1702 Oct 20, 2019
14e82d1
minor
Darryl1702 Oct 20, 2019
74ad826
Update article.md
hrodward Oct 21, 2019
cc3c01b
Update task.md
hrodward Oct 21, 2019
cd97f84
Update article.md
hrodward Oct 21, 2019
5c6be4c
Update article.md
hrodward Oct 21, 2019
8c1b767
Update article.md
hrodward Oct 21, 2019
3c8ae30
Update article.md
hrodward Oct 21, 2019
906dd13
Update task.md
hrodward Oct 21, 2019
7500898
Update task.md
hrodward Oct 21, 2019
c0fd76b
Update task.md
hrodward Oct 21, 2019
89c4a0f
Update article.md
hrodward Oct 21, 2019
4bb52fb
Update task.md
hrodward Oct 21, 2019
2d77eb7
Merge pull request #1483 from Ghost-017/patch-5
iliakan Oct 21, 2019
2cbed98
minor
iliakan Oct 21, 2019
77e9317
Merge pull request #1487 from hrodward/patch-13
iliakan Oct 21, 2019
ea50619
Merge pull request #1488 from hrodward/patch-14
iliakan Oct 21, 2019
ddf9d1e
Merge pull request #1489 from hrodward/patch-15
iliakan Oct 21, 2019
5db94bb
Merge pull request #1490 from hrodward/patch-16
iliakan Oct 21, 2019
e577658
Merge pull request #1491 from hrodward/patch-17
iliakan Oct 21, 2019
e5674cf
Merge pull request #1493 from hrodward/patch-19
iliakan Oct 21, 2019
e661044
Merge pull request #1494 from hrodward/patch-20
iliakan Oct 21, 2019
50aa158
Merge pull request #1495 from hrodward/patch-21
iliakan Oct 21, 2019
5aea931
Merge pull request #1496 from hrodward/patch-22
iliakan Oct 21, 2019
040aea0
Merge pull request #1497 from hrodward/patch-23
iliakan Oct 21, 2019
7a6a566
minor
iliakan Oct 21, 2019
09d2e96
Update article.md
paroche Oct 21, 2019
7a0fbdb
Update article.md
paroche Oct 21, 2019
88cd022
Update article.md
lex111 Oct 21, 2019
dd52fb9
Fixed object variable user.go() to be obj.go()
Oct 21, 2019
022c037
Update article.md
paroche Oct 22, 2019
00d3f99
Merge pull request #1499 from javascript-tutorial/paroche-patch-5
paroche Oct 22, 2019
f430bea
Update article.md
paroche Oct 22, 2019
0932380
Update article.md
paroche Oct 22, 2019
d0b95aa
Update 1-js/08-prototypes/01-prototype-inheritance/article.md
hrodward Oct 22, 2019
6219338
Update article.md
hrodward Oct 22, 2019
a04d80c
Update article.md
hrodward Oct 22, 2019
9151079
Fixed object variable user.go() to be obj.go() (#1498)
lex111 Oct 22, 2019
01bb684
Merge pull request #1471 from hrodward/patch-8
iliakan Oct 22, 2019
c07eb5c
Update article.md
paroche Oct 22, 2019
29ea890
Merge branch 'master' into patch-18
lex111 Oct 22, 2019
2e5fa78
minor
iliakan Oct 22, 2019
00ebc81
Update article.md
hrodward Oct 22, 2019
33cca1b
Fix confusion in the task
lex111 Oct 22, 2019
b6404a6
Update article.md
hrodward Oct 23, 2019
ab55453
Update article.md
hrodward Oct 23, 2019
6f8ad3c
Update article.md
hrodward Oct 23, 2019
ad939bb
Update article.md
hrodward Oct 23, 2019
cc3795f
Update article.md
paroche Oct 24, 2019
f6ead73
Update article.md
paroche Oct 24, 2019
c8e062f
Update article.md
paroche Oct 24, 2019
f954987
Update article.md
paroche Oct 24, 2019
a2d32ad
Update article.md (#1506)
lex111 Oct 24, 2019
eb2b327
Update task.md
hrodward Oct 24, 2019
fab771f
Update article.md (#1511)
lex111 Oct 24, 2019
373a305
Update article.md (#1510)
lex111 Oct 24, 2019
31d96a3
Update article.md (#1509)
lex111 Oct 24, 2019
7f28d56
Update article.md (#1507)
lex111 Oct 24, 2019
0007368
Update article.md
hrodward Oct 25, 2019
7df2a19
Update article.md (#1517)
lex111 Oct 25, 2019
072fa7d
minor
iliakan Oct 25, 2019
ead158a
Update article.md
hrodward Oct 25, 2019
9909b90
minor
iliakan Oct 25, 2019
c62c84c
Merge pull request #1492 from hrodward/patch-18
iliakan Oct 25, 2019
321519e
Merge pull request #1518 from hrodward/patch-22
iliakan Oct 25, 2019
86891b9
Merge pull request #1514 from hrodward/patch-32
iliakan Oct 25, 2019
fac4413
Merge pull request #1504 from hrodward/patch-24
iliakan Oct 25, 2019
8d3fbcc
Fix typo.
carsca Oct 25, 2019
a0168c7
Update article.md
hrodward Oct 25, 2019
f2501bc
fix typo (#1520)
lex111 Oct 25, 2019
2bd1854
Update solution.md
hrodward Oct 25, 2019
d048324
Merge pull request #1505 from hrodward/patch-25
iliakan Oct 26, 2019
ec91bab
Merge pull request #1521 from hrodward/patch-24
iliakan Oct 26, 2019
db1e31b
Merge pull request #1519 from hrodward/patch-22
iliakan Oct 26, 2019
70ca842
minor
iliakan Oct 26, 2019
ba9e2d4
merging all conflicts
iliakan Oct 28, 2019
88579ce
Resolve merge conflicts
Oct 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 1-js/04-object-basics/04-object-methods/3-why-this/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ importance: 3

# Explain the value of "this"

In the code below we intend to call `user.go()` method 4 times in a row.
In the code below we intend to call `obj.go()` method 4 times in a row.

But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why?

Expand Down
4 changes: 2 additions & 2 deletions 1-js/05-data-types/05-array-methods/4-sort-back/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ importance: 4

---

# Sort in the reverse order
# Sort in decreasing order

```js
let arr = [5, 2, 1, -10, 8];

// ... your code to sort it in the reverse order
// ... your code to sort it in decreasing order

alert( arr ); // 8, 5, 2, 1, -10
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ For server-side JavaScript, that limitation does not exist, and there exist othe

- Methods `setTimeout(func, delay, ...args)` and `setInterval(func, delay, ...args)` allow us to run the `func` once/regularly after `delay` milliseconds.
- To cancel the execution, we should call `clearTimeout/clearInterval` with the value returned by `setTimeout/setInterval`.
- Nested `setTimeout` calls is a more flexible alternative to `setInterval`, allowing us to set the time *between* executions more precisely.
- Nested `setTimeout` calls are a more flexible alternative to `setInterval`, allowing us to set the time *between* executions more precisely.
- Zero delay scheduling with `setTimeout(func, 0)` (the same as `setTimeout(func)`) is used to schedule the call "as soon as possible, but after the current script is complete".
- The browser limits the minimal delay for five or more nested call of `setTimeout` or for `setInterval` (after 5th call) to 4ms. That's for historical reasons.

Expand Down
2 changes: 1 addition & 1 deletion 1-js/06-advanced-functions/10-bind/6-ask-partial/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The task is a little more complex variant of <info:task/question-use-bind>.

The `user` object was modified. Now instead of two functions `loginOk/loginFail`, it has a single function `user.login(true/false)`.

What to pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`?
What should we pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`?

```js
function askPassword(ok, fail) {
Expand Down
2 changes: 1 addition & 1 deletion 1-js/06-advanced-functions/10-bind/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Functions provide a built-in method [bind](mdn:js/Function/bind) that allows to
The basic syntax is:

```js
// more complex syntax will be little later
// more complex syntax will come a little later
let boundFunc = func.bind(context);
```

Expand Down
10 changes: 5 additions & 5 deletions 1-js/06-advanced-functions/12-arrow-functions/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ Here we had to create additional variables `args` and `ctx` so that the function

Arrow functions:

- Do not have `this`.
- Do not have `arguments`.
- Can't be called with `new`.
- (They also don't have `super`, but we didn't study it. Will be in the chapter <info:class-inheritance>).
- Do not have `this`
- Do not have `arguments`
- Can't be called with `new`
- They also don't have `super`, but we didn't study it yet. We will on the chapter <info:class-inheritance>

That's because they are meant for short pieces of code that do not have their own "context", but rather works in the current one. And they really shine in that use case.
That's because they are meant for short pieces of code that do not have their own "context", but rather work in the current one. And they really shine in that use case.
8 changes: 4 additions & 4 deletions 1-js/07-object-properties/01-property-descriptors/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

As we know, objects can store properties.

Till now, a property was a simple "key-value" pair to us. But an object property is actually a more flexible and powerful thing.
Until now, a property was a simple "key-value" pair to us. But an object property is actually a more flexible and powerful thing.

In this chapter we'll study additional configuration options, and in the next we'll see how to invisibly turn them into getter/setter functions.

Expand Down Expand Up @@ -134,7 +134,7 @@ let user = { };
Object.defineProperty(user, "name", {
*!*
value: "John",
// for new properties need to explicitly list what's true
// for new properties we need to explicitly list what's true
enumerable: true,
configurable: true
*/!*
Expand All @@ -148,7 +148,7 @@ user.name = "Pete"; // Error

Now let's add a custom `toString` to `user`.

Normally, a built-in `toString` for objects is non-enumerable, it does not show up in `for..in`. But if we add `toString` of our own, then by default it shows up in `for..in`, like this:
Normally, a built-in `toString` for objects is non-enumerable, it does not show up in `for..in`. But if we add a `toString` of our own, then by default it shows up in `for..in`, like this:

```js run
let user = {
Expand All @@ -162,7 +162,7 @@ let user = {
for (let key in user) alert(key); // name, toString
```

If we don't like it, then we can set `enumerable:false`. Then it won't appear in `for..in` loop, just like the built-in one:
If we don't like it, then we can set `enumerable:false`. Then it won't appear in a `for..in` loop, just like the built-in one:

```js run
let user = {
Expand Down
6 changes: 3 additions & 3 deletions 1-js/07-object-properties/02-property-accessors/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

There are two kinds of properties.

The first kind is *data properties*. We already know how to work with them. All properties that we've been using till now were data properties.
The first kind is *data properties*. We already know how to work with them. All properties that we've been using until now were data properties.

The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code.

Expand Down Expand Up @@ -189,9 +189,9 @@ Technically, external code is able to access the name directly by using `user._n

## Using for compatibility

One of the great uses of accessors -- they allow to take control over a "regular" data property at any moment by replacing it with getter and setter and tweak its behavior.
One of the great uses of accessors is that they allow to take control over a "regular" data property at any moment by replacing it with a getter and a setter and tweak its behavior.

Imagine, we started implementing user objects using data properties `name` and `age`:
Imagine we started implementing user objects using data properties `name` and `age`:

```js
function User(name, age) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ importance: 5

The task has two parts.

We have objects:
Given the following objects:

```js
let head = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ importance: 5

---

# Where it writes?
# Where does it write?

We have `rabbit` inheriting from `animal`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Why two hamsters are full?
# Why are both hamsters full?

We have two hamsters: `speedy` and `lazy` inheriting from the general `hamster` object.

When we feed one of them, the other one is also full. Why? How to fix it?
When we feed one of them, the other one is also full. Why? How can we fix it?

```js run
let hamster = {
Expand Down
10 changes: 5 additions & 5 deletions 1-js/08-prototypes/01-prototype-inheritance/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ rabbit.__proto__ = animal;
```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`"
Please note that `__proto__` is *not the same* as `[[Prototype]]`. That's a getter/setter for it.

It exists for historical reasons, in modern language it is replaced with functions `Object.getPrototypeOf/Object.setPrototypeOf` that also get/set the prototype. We'll study the reasons for that and these functions later.
It exists for historical reasons. In modern language it is replaced with functions `Object.getPrototypeOf/Object.setPrototypeOf` that also get/set the prototype. We'll study the reasons for that and these functions later.

By the specification, `__proto__` must only be supported by browsers, but in fact all environments including server-side support it. For now, as `__proto__` notation is a little bit more intuitively obvious, we'll use it in the examples.
```
Expand Down Expand Up @@ -203,7 +203,7 @@ Here in the line `(*)` the property `admin.fullName` has a getter in the prototy

## The value of "this"

An interesting question may arise in the example above: what's the value of `this` inside `set fullName(value)`? Where the properties `this.name` and `this.surname` are written: into `user` or `admin`?
An interesting question may arise in the example above: what's the value of `this` inside `set fullName(value)`? Where are the properties `this.name` and `this.surname` written: into `user` or `admin`?

The answer is simple: `this` is not affected by prototypes at all.

Expand Down Expand Up @@ -246,13 +246,13 @@ The resulting picture:

![](proto-animal-rabbit-walk-3.svg)

If we had other objects like `bird`, `snake` etc inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method call would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects.
If we had other objects, like `bird`, `snake`, etc., inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method call would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects.

As a result, methods are shared, but the object state is not.

## for..in loop

The `for..in` loops over inherited properties too.
The `for..in` loop iterates over inherited properties too.

For instance:

Expand All @@ -267,7 +267,7 @@ let rabbit = {
};

*!*
// Object.keys only return own keys
// Object.keys only returns own keys
alert(Object.keys(rabbit)); // jumps
*/!*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ alert( rabbit.eats ); // true
```


1. We added one more string (emphasized), what `alert` shows now?
1. We added one more string (emphasized). What will `alert` show now?

```js
function Rabbit() {}
Expand Down Expand Up @@ -54,7 +54,7 @@ alert( rabbit.eats ); // true
alert( rabbit.eats ); // ?
```

3. Like this (replaced one line)?
3. And like this (replaced one line)?

```js
function Rabbit() {}
Expand Down
6 changes: 3 additions & 3 deletions 1-js/08-prototypes/02-function-prototype/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Remember, new objects can be created with a constructor function, like `new F()`.

If `F.prototype` is an object, then `new` operator uses it to set `[[Prototype]]` for the new object.
If `F.prototype` is an object, then the `new` operator uses it to set `[[Prototype]]` for the new object.

```smart
JavaScript had prototypal inheritance from the beginning. It was one of the core features of the language.
Expand Down Expand Up @@ -158,9 +158,9 @@ Rabbit.prototype = {

In this chapter we briefly described the way of setting a `[[Prototype]]` for objects created via a constructor function. Later we'll see more advanced programming patterns that rely on it.

Everything is quite simple, just few notes to make things clear:
Everything is quite simple, just a few notes to make things clear:

- The `F.prototype` property (don't mess with `[[Prototype]]`) sets `[[Prototype]]` of new objects when `new F()` is called.
- The `F.prototype` property (don't mistake it for `[[Prototype]]`) sets `[[Prototype]]` of new objects when `new F()` is called.
- The value of `F.prototype` should be either an object or `null`: other values won't work.
- The `"prototype"` property only has such a special effect when set on a constructor function, and invoked with `new`.

Expand Down
22 changes: 11 additions & 11 deletions 1-js/08-prototypes/03-native-prototypes/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ alert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects

The most intricate thing happens with strings, numbers and booleans.

As we remember, they are not objects. But if we try to access their properties, then temporary wrapper objects are created using built-in constructors `String`, `Number`, `Boolean`, they provide the methods and disappear.
As we remember, they are not objects. But if we try to access their properties, temporary wrapper objects are created using built-in constructors `String`, `Number` and `Boolean`. They provide the methods and disappear.

These objects are created invisibly to us and most engines optimize them out, but the specification describes it exactly this way. Methods of these objects also reside in prototypes, available as `String.prototype`, `Number.prototype` and `Boolean.prototype`.

```warn header="Values `null` and `undefined` have no object wrappers"
Special values `null` and `undefined` stand apart. They have no object wrappers, so methods and properties are not available for them. And there are no corresponding prototypes too.
Special values `null` and `undefined` stand apart. They have no object wrappers, so methods and properties are not available for them. And there are no corresponding prototypes either.
```

## Changing native prototypes [#native-prototype-change]
Expand All @@ -129,9 +129,9 @@ So, generally, modifying a native prototype is considered a bad idea.

**In modern programming, there is only one case where modifying native prototypes is approved. That's polyfilling.**

Polyfilling is a term for making a substitute for a method that exists in JavaScript specification, but is not yet supported by current JavaScript engine.
Polyfilling is a term for making a substitute for a method that exists in the JavaScript specification, but is not yet supported by a particular JavaScript engine.

Then we may implement it manually and populate the built-in prototype with it.
We may then implement it manually and populate the built-in prototype with it.

For instance:

Expand All @@ -144,7 +144,7 @@ if (!String.prototype.repeat) { // if there's no such method

// actually, the code should be a little bit more complex than that
// (the full algorithm is in the specification)
// but even an imperfect polyfill is often considered good enough for use
// but even an imperfect polyfill is often considered good enough
return new Array(n + 1).join(this);
};
}
Expand Down Expand Up @@ -179,18 +179,18 @@ obj.join = Array.prototype.join;
alert( obj.join(',') ); // Hello,world!
```

It works, because the internal algorithm of the built-in `join` method only cares about the correct indexes and the `length` property, it doesn't check that the object is indeed the array. And many built-in methods are like that.
It works because the internal algorithm of the built-in `join` method only cares about the correct indexes and the `length` property. It doesn't check if the object is indeed an array. Many built-in methods are like that.

Another possibility is to inherit by setting `obj.__proto__` to `Array.prototype`, so all `Array` methods are automatically available in `obj`.

But that's impossible if `obj` already inherits from another object. Remember, we only can inherit from one object at a time.

Borrowing methods is flexible, it allows to mix functionality from different objects if needed.
Borrowing methods is flexible, it allows to mix functionalities from different objects if needed.

## Summary

- All built-in objects follow the same pattern:
- The methods are stored in the prototype (`Array.prototype`, `Object.prototype`, `Date.prototype` etc).
- The object itself stores only the data (array items, object properties, the date).
- Primitives also store methods in prototypes of wrapper objects: `Number.prototype`, `String.prototype`, `Boolean.prototype`. Only `undefined` and `null` do not have wrapper objects.
- Built-in prototypes can be modified or populated with new methods. But it's not recommended to change them. Probably the only allowable case is when we add-in a new standard, but not yet supported by the engine JavaScript method.
- The methods are stored in the prototype (`Array.prototype`, `Object.prototype`, `Date.prototype`, etc.)
- The object itself stores only the data (array items, object properties, the date)
- Primitives also store methods in prototypes of wrapper objects: `Number.prototype`, `String.prototype` and `Boolean.prototype`. Only `undefined` and `null` do not have wrapper objects
- Built-in prototypes can be modified or populated with new methods. But it's not recommended to change them. The only allowable case is probably when we add-in a new standard, but it's not yet supported by the JavaScript engine
Loading