1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

edit docs/symbol

This commit is contained in:
ruanyf 2016-01-29 09:25:39 +08:00
parent ed283d0207
commit fc01552d64
4 changed files with 107 additions and 20 deletions

View File

@ -429,7 +429,7 @@ function add([x, y]){
add([1, 2]) // 3 add([1, 2]) // 3
``` ```
上面代码中,函数`add`的参数实际上不是一个数组,而是通过解构得到的变量`x``y` 上面代码中,函数`add`的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量`x``y`。对于函数内部的代码来说,它们能感受到的参数就是`x``y`
下面是另一个例子。 下面是另一个例子。

View File

@ -2,9 +2,9 @@
## Promise的含义 ## Promise的含义
`Promise`在JavaScript语言早有实现ES6将其写进了语言标准统一了用法原生提供了`Promise`对象。 Promise是异步编程的一种解决方案比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现ES6将其写进了语言标准统一了用法原生提供了`Promise`对象。
所谓`Promise`就是一个对象用来传递异步操作的消息。它代表了某个未来才会知道结果的事件通常是一个异步操作并且这个事件提供统一的API可供进一步处理。 所谓`Promise`简单说就是一个容器里面保存着某个未来才会结束的事件通常是一个异步操作的结果。从语法上说Promise是一个对象从它可以获取异步操作的消息。Promise提供统一的API各种异步操作都可以用同样的方法进行处理。
`Promise`对象有以下两个特点。 `Promise`对象有以下两个特点。
@ -68,6 +68,27 @@ timeout(100).then((value) => {
上面代码中,`timeout`方法返回一个Promise实例表示一段时间以后才会发生的结果。过了指定的时间`ms`参数以后Promise实例的状态变为Resolved就会触发`then`方法绑定的回调函数。 上面代码中,`timeout`方法返回一个Promise实例表示一段时间以后才会发生的结果。过了指定的时间`ms`参数以后Promise实例的状态变为Resolved就会触发`then`方法绑定的回调函数。
Promise新建后就会立即执行。
```javascript
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('Resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// Resolved
```
上面代码中Promise新建后立即执行所以首先输出的是“Promise”。然后`then`方法指定的回调函数将在当前脚本所有同步任务执行完才会执行所以“Resolved”最后输出。
下面是异步加载图片的例子。 下面是异步加载图片的例子。
```javascript ```javascript
@ -198,7 +219,7 @@ getJSON("/post/1.json").then(
## Promise.prototype.catch() ## Promise.prototype.catch()
Promise.prototype.catch方法是`.then(null, rejection)`的别名,用于指定发生错误时的回调函数。 `Promise.prototype.catch`方法是`.then(null, rejection)`的别名,用于指定发生错误时的回调函数。
```javascript ```javascript
getJSON("/posts.json").then(function(posts) { getJSON("/posts.json").then(function(posts) {
@ -209,7 +230,7 @@ getJSON("/posts.json").then(function(posts) {
}); });
``` ```
上面代码中,`getJSON`方法返回一个Promise对象如果该对象状态变为Resolved则会调用`then`方法指定的回调函数如果异步操作抛出错误状态就会变为Rejected就会调用`catch`方法指定的回调函数,处理这个错误。 上面代码中,`getJSON`方法返回一个Promise对象如果该对象状态变为`Resolved`,则会调用`then`方法指定的回调函数;如果异步操作抛出错误,状态就会变为`Rejected`,就会调用`catch`方法指定的回调函数,处理这个错误。
```javascript ```javascript
p.then((val) => console.log("fulfilled:", val)) p.then((val) => console.log("fulfilled:", val))
@ -225,15 +246,41 @@ p.then((val) => console.log(fulfilled:", val))
```javascript ```javascript
var promise = new Promise(function(resolve, reject) { var promise = new Promise(function(resolve, reject) {
throw new Error('test') throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
}); });
promise.catch(function(error) { console.log(error) });
// Error: test // Error: test
``` ```
上面代码中Promise抛出一个错误就被`catch`方法指定的回调函数捕获。 上面代码中Promise抛出一个错误就被`catch`方法指定的回调函数捕获。注意,上面的写法与下面两种写法是等价的。
如果Promise状态已经变成resolved再抛出错误是无效的。 ```javascript
// 写法一
var promise = new Promise(function(resolve, reject) {
try {
throw new Error('test');
} catch(e) {
reject(e);
}
});
promise.catch(function(error) {
console.log(error);
});
// 写法二
var promise = new Promise(function(resolve, reject) {
reject(new Error('test'));
});
promise.catch(function(error) {
console.log(error);
});
```
比较上面两种写法,可以发现`reject`方法的作用,等同于抛出错误。
如果Promise状态已经变成`Resolved`,再抛出错误是无效的。
```javascript ```javascript
var promise = new Promise(function(resolve, reject) { var promise = new Promise(function(resolve, reject) {
@ -300,7 +347,7 @@ someAsyncThing().then(function() {
}); });
``` ```
上面代码中,`someAsyncThing`函数产生的Promise对象会报错但是由于没有指定`catch`方法,这个错误不会被捕获,也不会传递到外层代码,导致运行后没有任何输出。 上面代码中,`someAsyncThing`函数产生的Promise对象会报错但是由于没有指定`catch`方法,这个错误不会被捕获,也不会传递到外层代码,导致运行后没有任何输出。注意Chrome浏览器不遵守这条规定它会抛出错误“ReferenceError: x is not defined”。
```javascript ```javascript
var promise = new Promise(function(resolve, reject) { var promise = new Promise(function(resolve, reject) {
@ -312,7 +359,7 @@ promise.then(function(value) { console.log(value) });
// Uncaught Error: test // Uncaught Error: test
``` ```
上面代码中Promise指定在下一轮“事件循环”再抛出错误结果由于没有指定使用try...catch语句就冒泡到最外层成了未捕获的错误。因为此时Promise的函数体已经运行结束了所以这个错误是在Promise函数体外抛出的。 上面代码中Promise指定在下一轮“事件循环”再抛出错误结果由于没有指定使用`try...catch`语句就冒泡到最外层成了未捕获的错误。因为此时Promise的函数体已经运行结束了所以这个错误是在Promise函数体外抛出的。
Node.js有一个`unhandledRejection`事件,专门监听未捕获的`reject`错误。 Node.js有一个`unhandledRejection`事件,专门监听未捕获的`reject`错误。
@ -482,7 +529,7 @@ p.catch(error => console.log(error))
## Promise.resolve() ## Promise.resolve()
有时需要将现有对象转为Promise对象Promise.resolve方法就起到这个作用。 有时需要将现有对象转为Promise对象`Promise.resolve`方法就起到这个作用。
```javascript ```javascript
var jsPromise = Promise.resolve($.ajax('/whatever.json')); var jsPromise = Promise.resolve($.ajax('/whatever.json'));
@ -498,7 +545,44 @@ Promise.resolve('foo')
new Promise(resolve => resolve('foo')) new Promise(resolve => resolve('foo'))
``` ```
如果Promise.resolve方法的参数不是具有then方法的对象又称thenable对象则返回一个新的Promise对象且它的状态为Resolved。 `Promise.resolve`方法的参数分成四种情况。
**1参数是一个Promise实例**
如果参数是Promise实例那么`Promise.resolve`将不做任何修改、原封不动地返回这个实例。
**2参数是一个`thenable`对象**
`thenable`对象指的是具有`then`方法的对象,比如下面这个对象。
```javascript
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
```
`Promise.resolve`方法会将这个对象转为Promise对象然后就立即执行`thenable`对象的`then`方法。
```javascript
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
```
上面代码中,`thenable`对象的`then`方法执行后,对象`p1`的状态就变为`resolved`,从而立即执行最后那个`then`方法指定的回调函数输出42。
**3参数不是具有`then`方法的对象,或根本就不是对象**
如果参数是一个原始值,或者是一个不具有`then`方法的对象,则`Promise.resolve`方法返回一个新的Promise对象状态为`Resolved`
```javascript ```javascript
var p = Promise.resolve('Hello'); var p = Promise.resolve('Hello');
@ -509,9 +593,13 @@ p.then(function (s){
// Hello // Hello
``` ```
上面代码生成一个新的Promise对象的实例p。由于字符串Hello不属于异步操作判断方法是它不是具有then方法的对象返回Promise实例的状态从一生成就是Resolved所以回调函数会立即执行。Promise.resolve方法的参数会同时传给回调函数。 上面代码生成一个新的Promise对象的实例`p`。由于字符串`Hello`不属于异步操作判断方法是它不是具有then方法的对象返回Promise实例的状态从一生成就是`Resolved`,所以回调函数会立即执行。`Promise.resolve`方法的参数,会同时传给回调函数。
Promise.resolve方法允许调用时不带参数。所以如果希望得到一个Promise对象比较方便的方法就是直接调用Promise.resolve方法。 **4不带有任何参数**
`Promise.resolve`方法允许调用时不带参数,直接返回一个`Resolved`状态的Promise对象。
所以如果希望得到一个Promise对象比较方便的方法就是直接调用`Promise.resolve`方法。
```javascript ```javascript
var p = Promise.resolve(); var p = Promise.resolve();
@ -521,13 +609,11 @@ p.then(function () {
}); });
``` ```
上面代码的变量p就是一个Promise对象。 上面代码的变量`p`就是一个Promise对象。
如果Promise.resolve方法的参数是一个Promise实例则会被原封不动地返回。
## Promise.reject() ## Promise.reject()
`Promise.reject(reason)`方法也会返回一个新的Promise实例该实例的状态为`rejected``Promise.reject`方法的参数`reason`,会被传递给实例的回调函数 `Promise.reject(reason)`方法也会返回一个新的Promise实例该实例的状态为`rejected`它的参数用法与`Promise.resolve`方法完全一致
```javascript ```javascript
var p = Promise.reject('出错了'); var p = Promise.reject('出错了');

View File

@ -190,6 +190,7 @@
## 工具 ## 工具
- Babel, [Babel Handbook](https://github.com/thejameskyle/babel-handbook/tree/master/translations/en): Babel的用法介绍
- Google, [traceur-compiler](https://github.com/google/traceur-compiler): Traceur编译器 - Google, [traceur-compiler](https://github.com/google/traceur-compiler): Traceur编译器
- Casper Beyer, [ECMAScript 6 Features and Tools](http://caspervonb.github.io/2014/03/05/ecmascript6-features-and-tools.html) - Casper Beyer, [ECMAScript 6 Features and Tools](http://caspervonb.github.io/2014/03/05/ecmascript6-features-and-tools.html)
- Stoyan Stefanov, [Writing ES6 today with jstransform](http://www.phpied.com/writing-es6-today-with-jstransform/) - Stoyan Stefanov, [Writing ES6 today with jstransform](http://www.phpied.com/writing-es6-today-with-jstransform/)

View File

@ -383,7 +383,7 @@ iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo')
### Symbol.hasInstance ### Symbol.hasInstance
对象的`Symbol.hasInstance`属性,指向一个内部方法。该对象使用`instanceof`运算符时,会调用这个方法,判断该对象是否为某个构造函数的实例。比如,`foo instanceof Foo`在语言内部,实际调用的是`Foo[Symbol.hasInstance](foo)` 对象的`Symbol.hasInstance`属性,指向一个内部方法。当其他对象使用`instanceof`运算符,判断是否为该对象的实例时,会调用这个方法。比如,`foo instanceof Foo`在语言内部,实际调用的是`Foo[Symbol.hasInstance](foo)`
```javascript ```javascript
class MyClass { class MyClass {