fixes
This commit is contained in:
parent
0b55d45daf
commit
3caa91137e
8 changed files with 21 additions and 33 deletions
|
@ -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/>.
|
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.
|
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".
|
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.
|
JavaScript is a developing language, new features get added regularly.
|
||||||
|
|
||||||
|
|
|
@ -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.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).
|
- [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.
|
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));
|
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.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.
|
- [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.
|
- [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`.
|
- [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`.
|
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`.
|
||||||
|
|
|
@ -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`.
|
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.
|
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).
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
But built-in classes are an exception. They don't inherit statics from each other.
|
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`:
|
Here's the picture structure for `Date` and `Object`:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
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`.
|
||||||
|
|
|
@ -107,7 +107,7 @@ As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that mean
|
||||||
|
|
||||||
Now let's make a mixin for real life.
|
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.
|
- 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.
|
- 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.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Generators
|
# Generators
|
||||||
|
|
||||||
Regular functions return only one, single value (or nothing).
|
Regular functions return only one, single value (or nothing).
|
||||||
|
@ -224,8 +223,6 @@ let range = {
|
||||||
alert( [...range] ); // 1,2,3,4,5
|
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:
|
That works, because `range[Symbol.iterator]()` now returns a generator, and generator methods are exactly what `for..of` expects:
|
||||||
- it has `.next()` method
|
- it has `.next()` method
|
||||||
- that returns values in the form `{value: ..., done: true/false}`
|
- that returns values in the form `{value: ..., done: true/false}`
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Dynamic imports
|
# Dynamic imports
|
||||||
|
|
||||||
Export and import statements that we covered in previous chapters are called "static".
|
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();
|
hi();
|
||||||
bye();
|
bye();
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, for the default export:
|
Or, if `say.js` has the default export:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// 📁 say.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:
|
So, the dynamic import will be like this:
|
||||||
|
|
||||||
```js
|
```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();
|
say();
|
||||||
```
|
```
|
||||||
|
@ -91,12 +89,12 @@ Here's the full example:
|
||||||
|
|
||||||
[codetabs src="say" current="index.html"]
|
[codetabs src="say" current="index.html"]
|
||||||
|
|
||||||
So, dynamic imports are very simple to use, and they allow to import modules at run-time.
|
```smart
|
||||||
|
Dynamic imports work in regular scripts, they don't require `script type="module"`.
|
||||||
Also, dynamic imports work in regular scripts, they don't require `script type="module"`.
|
```
|
||||||
|
|
||||||
```smart
|
```smart
|
||||||
Although `import()` looks like a function call, it's a special syntax that just happens to use parentheses (similar to `super()`).
|
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.
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Proxy and Reflect
|
# 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.
|
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.
|
||||||
|
@ -175,7 +174,7 @@ dictionary = new Proxy(dictionary, ...);
|
||||||
numbers = new Proxy(numbers, ...);
|
numbers = new Proxy(numbers, ...);
|
||||||
```
|
```
|
||||||
|
|
||||||
The proxy should totally replace the target object everywhere. No one should ever reference the target object after it got proxied. Otherwise it 's easy to mess up.
|
The proxy should totally replace the target object everywhere. No one should ever reference the target object after it got proxied. Otherwise it's easy to mess up.
|
||||||
````
|
````
|
||||||
|
|
||||||
## Validation with "set" trap
|
## Validation with "set" trap
|
||||||
|
|
|
@ -22,7 +22,7 @@ function sayHi() {
|
||||||
alert("Hello");
|
alert("Hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
// global functions are methods of the global objecct:
|
// global functions are methods of the global object:
|
||||||
window.sayHi();
|
window.sayHi();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue