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/>.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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`:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
|
|
@ -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}`
|
||||
|
|
|
@ -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.
|
||||
```
|
||||
|
|
|
@ -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.
|
||||
|
@ -175,7 +174,7 @@ dictionary = new Proxy(dictionary, ...);
|
|||
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
|
||||
|
|
|
@ -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();
|
||||
```
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue