This commit is contained in:
Ilya Kantor 2019-07-18 12:24:31 +03:00
parent 0b55d45daf
commit 3caa91137e
8 changed files with 21 additions and 33 deletions

View file

@ -11,7 +11,7 @@ But being that formalized, it's difficult to understand at first. So if you need
The latest draft is at <https://tc39.es/ecma262/>.
To read about new bleeding-edge features, that are "almost standard", see proposals at <https://github.com/tc39/proposals>.
To read about new bleeding-edge features, including those that are "almost standard" (so-called "stage 3"), see proposals at <https://github.com/tc39/proposals>.
Also, if you're in developing for the browser, then there are other specs covered in the [second part](info:browser-environment) of the tutorial.
@ -28,7 +28,7 @@ Also, if you're in developing for the browser, then there are other specs covere
Also, we can use an internet search with phrases such as "RegExp MSDN" or "RegExp MSDN jscript".
## Feature support
## Compatibility tables
JavaScript is a developing language, new features get added regularly.

View file

@ -179,7 +179,7 @@ Modern methods to setup and directly access the prototype are:
- [Object.getPrototypeOf(obj)](mdn:js/Object.getPrototypeOf) -- returns the `[[Prototype]]` of `obj` (same as `__proto__` getter).
- [Object.setPrototypeOf(obj, proto)](mdn:js/Object.setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto` (same as `__proto__` setter).
The built-in `__proto__` getter/setter is unsafe if we'd want to put user-generated keys in to an object. Just because a user may enter "__proto__" as the key, and there'll be an error with hopefully easy, but generally unpredictable consequences.
The built-in `__proto__` getter/setter is unsafe if we'd want to put user-generated keys in to an object. Just because a user may enter `"__proto__"` as the key, and there'll be an error, with hopefully light, but generally unpredictable consequences.
So we can either use `Object.create(null)` to create a "very plain" object without `__proto__`, or stick to `Map` objects for that.
@ -189,6 +189,11 @@ Also, `Object.create` provides an easy way to shallow-copy an object with all de
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
```
We also made it clear that `__proto__` is a getter/setter for `[[Prototype]]` and resides in `Object.prototype`, just as other methods.
We can create an object without a prototype by `Object.create(null)`. Such objects are used as "pure dictionaries", they have no issues with `"__proto__"` as the key.
Other methods:
- [Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of enumerable own string property names/values/key-value pairs.
- [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- returns an array of all own symbolic keys.
@ -196,8 +201,4 @@ let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescr
- [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- returns an array of all own keys.
- [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) key named `key`.
We also made it clear that `__proto__` is a getter/setter for `[[Prototype]]` and resides in `Object.prototype`, just as other methods.
We can create an object without a prototype by `Object.create(null)`. Such objects are used as "pure dictionaries", they have no issues with `"__proto__"` as the key.
All methods that return object properties (like `Object.keys` and others) -- return "own" properties. If we want inherited ones, then we can use `for..in`.

View file

@ -70,21 +70,14 @@ Built-in objects have their own static methods, for instance `Object.keys`, `Arr
As we already know, native classes extend each other. For instance, `Array` extends `Object`.
Normally, when one class extends another, both static and non-static methods are inherited.
So, if `Rabbit extends Animal`, then:
1. `Rabbit.methods` are callable for `Animal.methods`, because `Rabbit.[[Prototype]] = Animal`.
2. `new Rabbit().methods` are also available, because `Rabbit.prototype.[[Prototype]] = Animal.prototype`.
That's thoroughly explained in the chapter [](info:static-properties-methods#statics-and-inheritance).
Normally, when one class extends another, both static and non-static methods are inherited. That was thoroughly explained in the chapter [](info:static-properties-methods#statics-and-inheritance).
But built-in classes are an exception. They don't inherit statics from each other.
For example, both `Array` and `Date` inherit from `Object`, so their instances have methods from `Object.prototype`. But `Array.[[Prototype]]` does not point to `Object`. So there's `Object.keys()`, but not `Array.keys()` and `Date.keys()`.
For example, both `Array` and `Date` inherit from `Object`, so their instances have methods from `Object.prototype`. But `Array.[[Prototype]]` does not reference `Object`, so there's no `Array.keys()` and `Date.keys()` static methods.
Here's the picture structure for `Date` and `Object`:
![](object-date-inheritance.png)
Note, there's no link between `Date` and `Object`. Both `Object` and `Date` exist independently. `Date.prototype` inherits from `Object.prototype`, but that's all.
As you can see, there's no link between `Date` and `Object`. They are independent, only `Date.prototype` inherits from `Object.prototype`.

View file

@ -107,7 +107,7 @@ As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that mean
Now let's make a mixin for real life.
An important feature of many browser objects (not only) is that they can generate events. Events is a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows to easily add event-related functions to any class/object.
An important feature of many browser objects (for instance) is that they can generate events. Events is a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows to easily add event-related functions to any class/object.
- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data.
- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from `.trigger` call.

View file

@ -1,4 +1,3 @@
# Generators
Regular functions return only one, single value (or nothing).
@ -224,8 +223,6 @@ let range = {
alert( [...range] ); // 1,2,3,4,5
```
The `range` object is now iterable.
That works, because `range[Symbol.iterator]()` now returns a generator, and generator methods are exactly what `for..of` expects:
- it has `.next()` method
- that returns values in the form `{value: ..., done: true/false}`

View file

@ -1,4 +1,3 @@
# Dynamic imports
Export and import statements that we covered in previous chapters are called "static".
@ -65,10 +64,9 @@ let {hi, bye} = await import('./say.js');
hi();
bye();
```
Or, for the default export:
Or, if `say.js` has the default export:
```js
// 📁 say.js
@ -77,12 +75,12 @@ export default function() {
}
```
To import it, we need to get `default` property of the module object, as explained in the [previous chapter](info:import-export).
...Then, in order to access it, we can use `default` property of the module object, as explained in the [previous chapter](info:import-export).
So, the dynamic import will be like this:
```js
let {default: say} = await import('./say.js'); // map .default to say variable
let {default: say} = await import('./say.js'); // save .default property in say variable
say();
```
@ -91,12 +89,12 @@ Here's the full example:
[codetabs src="say" current="index.html"]
So, dynamic imports are very simple to use, and they allow to import modules at run-time.
Also, dynamic imports work in regular scripts, they don't require `script type="module"`.
```smart
Dynamic imports work in regular scripts, they don't require `script type="module"`.
```
```smart
Although `import()` looks like a function call, it's a special syntax that just happens to use parentheses (similar to `super()`).
That means that import doesn't inherit from `Function.prototype` so we cannot call or apply it.
So we can't copy `import` to a variable or use `.call/apply` with it.
```

View file

@ -1,4 +1,3 @@
# Proxy and Reflect
A *proxy* wraps another object and intercepts operations, like reading/writing properties and others, optionally handling them on its own, or transparently allowing the object to handle them.

View file

@ -22,7 +22,7 @@ function sayHi() {
alert("Hello");
}
// global functions are methods of the global objecct:
// global functions are methods of the global object:
window.sayHi();
```