ES6+速查表
栏目: JavaScript · 发布时间: 5年前
内容简介:这份文档整理了在当前前端项目中经常需要查阅的内容,并给出了最新的代码示例。你或许会因为不熟悉当前一些新的代码库(例如 React)所用到的 JavaScript 概念,而很难上手这些新框架。所以本文档的目的并非从零教你 JavaScript,而是帮助已经有一定编程基础的你。
图: Ahmad Awais :zap:️
Modern JavaScript cheatsheet 中文版
简介
初心
这份文档整理了在当前前端项目中经常需要查阅的内容,并给出了最新的代码示例。
你或许会因为不熟悉当前一些新的代码库(例如 React)所用到的 JavaScript 概念,而很难上手这些新框架。所以本文档的目的并非从零教你 JavaScript,而是帮助已经有一定编程基础的你。
除此之外,我(作者: Manuel Beaudru )偶尔会写上一些我的小技巧,也会注意提示这只是我的个人提议。
注:这篇文档里提到的大多数概念来自于目前最新的 JavaScript(ES2015,即 ES6),你可以在 这里 查看新增的特性,网站做得很棒。
参考材料
当你觉得有的概念不容易理解时,你可以在下面的链接里面寻找答案。
- MDN (Mozilla Developer Network)
- You don’t know JS(书)
- ES6 新特性和例子
- WesBos 博客中 ES6 类别
- Reddit (JavaScript)
- Google 可直接查找特定的博客和资源
- StackOverflow
目录
- Modern JavaScript cheatsheet 中文版
正文
变量声明: var, const, let
在 JavaScript 中,声明变量时可以用三个不同的关键词,分别是 var
, let
以及 const
,它们各有异同。
简述
用 const
声明的变量,不能被重新赋值,而另两个 var
和 let
是可以的。
所以我建议默认情况下你都用 const
来声明变量,在你需要 改变 或是声明之后再重新指派它的时候,才用 let
来声明变量。
- | 作用域 | 是否可重新赋值 | 是否可变 | |
---|---|---|---|---|
const | 块级 | × | √ | |
let | 块级 | √ | √ | √ |
var | 函数 | √ | √ | × |
代码示例
const person= "Nick"; person= "John" // 因为 person 不能被重新赋值,所以会报错
let person = "Nick"; person = "John"; console.log(person) // "John", 使用 let 声明的变量可以重新赋值
详述
简单来讲,变量的作用域()是指“在这部分代码中可以访问到此变量”。
var
使用 var
定义的变量,其作用域是定义它的函数内部( function scoped ),也就是说在函数内部创建一个 var
变量的时候,在此函数内部可以任意访问这个变量,但在函数之外,这样的局部变量是无法被访问的。
我建议你这样理解,如果一个变量是 X 作用域(scoped) 类型的,那就是说这个变量是 X 的属性之一。(译注:X 有 function 和 block 两类,代表函数作用域和块级作用域。)
function myFunction() { var myVar = "Nick"; console.log(myVar); // "Nick" - 在这个函数中 myVar 可被访问到 } console.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问
继续来看变量的作用域,下面有更多精妙的例子:
function myFunction() { var myVar = "Nick"; if (true) { var myVar = "John"; console.log(myVar); // "John" // 实际上 myVar 是函数级作用域变量,重新声明的时候,相当于用 "John" 抹去了 myVar 之前的值 "Nick" } console.log(myVar); // "John" - 可见 if 块中的代码会如何影响变量 } console.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问
另外, var 声明的变量在执行的时候,就像会被移动到作用域的开始,这就是我们所说的 变量声明提升(var hoisting) 。
所以看下面这段代码:
console.log(myVar) // undefined -- 没有提示错误 var myVar= 2;
之所以没有发生错误,是因为它执行时会被解释为这样:
var myVar; console.log(myVar) // undefined -- 没有提示错误 myVar = 2;
let
var
和 let
几乎是一样的,但是用 let
声明的变量有如下特性:
- 块级作用域 ( block scoped )
- 在被赋值之前,是 无法 访问使用的
- 在同一个作用域之下,不能被重新声明
我们来看看之前例子中提到的块级作用域( block scoping )的效果:
function myFunction() { let myVar = "Nick"; if (true) { let myVar = "John"; console.log(myVar); // "John" // 实际上 myVar 是块级作用域的变量,在 if 块中,我们相当于是创建了一个新变量, // 这个变量在此块之外是无法被访问的,而且它完全区别于我们创建的第一个 myVar 变量! } console.log(myVar); // "Nick", 可见 if 块中的代码,并没有影响到这个变量的值 } console.log(myVar); // 抛出错误 ReferenceError,在函数外部无法访问到 myVar。
现在,来看看 let (和 const )声明的变量在赋值前无法访问是什么意思:
console.log(myVar) // 提示错误 ReferenceError ! let myVar= 2;
这就是它们和 var 变量的区别,如果你在还未赋值给 let 或者 const 变量之前,就想读写它,是会提示错误的。这种情况常被称作暂存死区( Temporal dead zone )或者 TDZ 。
注意:从技术上讲, let 和 const 变量声明时也存在提升,但并不代表它们的赋值也会被提升。但由于它被设计成了赋值之前无法使用,所以我们直观感觉上它没有被提升,但其实是存在提升的。如果想了解更多细节,请看 这篇文章 。
另外,在同一作用域内你不能重新声明一个 let 变量。
let myVar= 2; let myVar= 3; // 提示语法错误 SyntaxError
const
const
声明的变量很像 let
,但它不能被重新赋值。
总结一下 const
变量的特点如下:
- 块级作用域
- 赋值之前无法使用
- 在同一个作用域内部,你不能重新声明一个变量
- 不能被重新指派
const myVar= "Nick"; myVar= "John" // 提示错误,不允许重新赋值 const 变量
但这里有一个小细节: const
变量并非完全,如果这个变量是 object
和 array
类型的值,那它的值是 可以改变 的。assign
对于对象类型来说:
const person = { name: 'Nick' }; person.name = 'John' // 这会生效的!person 并非完全重新指派( reassigned ),只是值变化了( mutated ) console.log(person.name) // "John" person = "Sandra" // 提示错误,因为用 const 声明的变量不能被重新指派
对于数组类型来说:
const person = []; person.push('John'); // 这也会生效!person 并非完全重新指派( reassigned ),只是值变化了( mutated ) console.log(person[0]) // "John" person = ["Nick"] // 提示错误,因为用 const 声明的变量不能被重新指派
延伸资料
箭头函数
ES6 JS 的最新版本已经介绍了 箭头函数 , 箭头函数是以另一种方式声明和使用函数。以下是箭头函数带来的一些好处:
- 更加简洁
- 从上下文获取 this
- 隐式的返回方式
代码示例
- 简洁性和隐式的返回方式
function double(x) { return x* 2; } // 传统函数声明方式 console.log(double(2)) // 4
const double =x=>x* 2; // 同样的函数,使用具有隐式返回方式的箭头函数来表示 console.log(double(2)) // 4
- this 关键字
在箭头函数中, this 的值就等于函数所处的封闭的可执行上下文的 this 。简单来说,就是在箭头函数中,当你调用一个位于函数体内部的函数时,在内部函数中,你不需要使用”that = this” 这样的声明语句。
function myFunc() { this.myVar = 0; setTimeout(() => { this.myVar++; console.log(this.myVar) // 1 }, 0); }
详述
简洁性
箭头函数从很多方面都比传统的函数简洁。案例如下:
- 隐式返回 VS 显式返回
显式返回指的是函数的返回语句使用了return 关键字
function double(x) { return x * 2; // 使用了*return*关键字,显式返回 x * 2 }
传统函数总是伴随着显式返回。使用箭头函数,你可以使用 隐式返回 ,即不需要在函数体内使用return关键字就可以返回值。
隐式返回需要将所需代码写在一条语句中。
const double = (x) => { return x * 2; // 显式返回 }
鉴于只返回单值,我们可以使用隐式返回。
const double = (x) =>x* 2;
为实现隐式返回,我们只需要 移除花括号 和 return 关键字。之所以被称为 隐式 返回,是因为 return 关键字不存在的情况下,函数仍可返回 x * 2
。
注意:如果你的函数不是返回一个单值(伴有 连带值 ),那么既不可以使用显式返回也不可以使用隐式返回。
除此之外, 如果你想隐式返回一个 object 则必须使用圆括号对其修饰,
const getPerson= () => ({name: "Nick",age: 24 }) console.log(getPerson()) // { name: "Nick", age: 24 } -- 箭头函数返回的对象
- 函数只有一个参数
如果你的箭头函数只有一个参数,你可以省略修饰参数的圆括号,重新观察上面的代码:
const double = (x) =>x* 2; // 箭头函数只有一个参数
参数外面的圆括号可以省略:
const double =x=>x* 2; // 箭头函数只有一个参数
- 函数无参数
当箭头函数无参数时,必须使用圆括号,否则会出现语法错误.
() => { // 必须提供圆括号 const x = 2; return x; }
=> { // 无圆括号,错误! const x = 2; return x; }
this 关键字
要理解箭头函数中this的微妙之处,你必须首先了解JavaScript中的行为。
在箭头函数中, this 的值就等于函数所处的封闭可执行上下文的 this 。这句话的意思就是箭头函数不创建一个新的 this , 而是从其所处的上下文环境中获取。
没有箭头函数,如果你想要从 this 访问函数内部的函数中的一个变量,你必须使用 that = this 或者 self = this 这样的技巧。
例如, 使用位于myFunc内部的函数setTimeout:
function myFunc() { this.myVar = 0; var that = this; // that = this setTimeout( function() { // 在函数的内部创建一个新的 that.myVar++; console.log(that.myVar) // 1 console.log(this.myVar) // 未定义 -- 请参照上面的函数this定义 }, 0 ); }
但是一旦使用箭头函数, this 将从包含这个箭头函数的上下文中获取:
function myFunc() { this.myVar = 0; setTimeout( () => { // 从上下文中获取this, 在这里就是 myFunc this.myVar++; console.log(this.myVar) // 1 }, 0 ); }
相关资料
- Arrow functions introduction - WesBos
- JavaScript arrow function - MDN
- Arrow function and lexical this
函数参数默认值
从 ES2015 以后开始,你可以使用下面的语法,给你的方法参数来设置默认值
function myFunc(x = 10) { return x; } console.log(myFunc()) // 10 -- 没有值传入,所以默认的值10传给了myFunc console.log(myFunc(5)) // 5 -- 一个值被传入,所以x等于5 console.log(myFunc(undefined)) // 10 -- undefined 值提供了,所以默认值关联了x console.log(myFunc(null)) // null -- 提供了 (null) , 见一下详细解释
默认参数有且只有在以下两种情况下才会生效:
- 没有参数提供的时候
- undefined 参数被提供的时候
换句话说,如果你传入 NULL 默认值 将不会生效
注意: 默认值赋值也可以与析构参数一起使用(參见下一节的例子)。
相关资料
Objects 和 Arrays 解构
通过 解构 来从对象或数组中提取值来赋值给新变量非常方便。
举几个例子, 如 解构 可以用来解构函数参数或者 React 项目中的 this.props
对象。
代码示例
- Object
以下面这个对象为例:
const person = { firstName: "Nick", lastName: "Anderson", age: 35, sex: "M" }
不使用解构
const first = person.firstName; const age = person.age; const city = person.city || "Paris";
使用解构,只需一行:
const { firstName: first, age, city = "Paris" } = person; // That's it ! console.log(age) // 35 -- A new variable age is created and is equal to person.age console.log(first) // "Nick" -- A new variable first is created and is equal to person.firstName console.log(firstName) // ReferenceError -- person.firstName exists BUT the new variable created is named first console.log(city) // "Paris" -- A new variable city is created and since person.city is undefined, city is equal to the default value provided "Paris".
注意:在 const { age } = person;
中,关键词 const
后的花括号并 不是用来声明一个对象或块 ,仅仅是 解构 的语法。
- 函数参数
解构 经常用来解构函数的对象参数。
不使用解构
function joinFirstLastName(person) { const firstName = person.firstName; const lastName = person.lastName; return firstName + '-' + lastName; } joinFirstLastName(person); // "Nick-Anderson"
通过解构对象参数 person
, 我们得到了一个更简洁的函数:
function joinFirstLastName({ firstName, lastName }) { // we create firstName and lastName variables by destructuring person parameter return firstName + '-' + lastName; } joinFirstLastName(person); // "Nick-Anderson"
解构搭配 箭头函数 更棒:
const joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName; joinFirstLastName(person); // "Nick-Anderson"
- Array
以下面这个数组为例:
const myArray= ["a", "b", "c"];
不使用解构:
const x=myArray[0]; const y=myArray[1];
使用解构:
const [x, y] = myArray; // That's it ! console.log(x) // "a" console.log(y) // "b"
相关资料
Array 的操作方法 - map / filter / reduce
Map
, filter
和 reduce
是Array 的操作方法,来自于 函数式编程 的一个编程范例。
概括来说:
- Array.prototype.map() 接受一个数组,并对数组中的元素进行某些操作并返回转换后的元素的数组。
- Array.prototype.filter() 接受一个数组,依照元素本身決定是否保留,并將返回保留元素的数组。
- Array.prototype.reduce() 接受一个数组,并将这些值聚合成一个值(返回的值)
我建议在遵循函数式编程原则时尽可能地使用它们,因为它们是可组合的,简洁而优雅的。
有这三个方法,你可以在大多数情况下避免使用 for
和 forEach
循环。当你想要做一个for循环时,尝试用map,filter和reduce组合来做。一开始你可能很难做到这一点,因为它需要你学习一种新的思维方式,但是一旦你掌握了它就会变得很容易。
代码示例
const numbers = [0, 1, 2, 3, 4, 5, 6]; const doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12] const evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6] const sum = numbers.reduce((prev, next) => prev + next, 0); // 21
通过 Map
, filter
和 reduce
这几个方法计算出成绩大于等于10分的得分总和。
const students = [ { name: "Nick", grade: 10 }, { name: "John", grade: 15 }, { name: "Julia", grade: 19 }, { name: "Nathalie", grade: 9 }, ]; const aboveTenSum = students .map(student => student.grade) // we map the students array to an array of their grades .filter(grade => grade >= 10) // we filter the grades array to keep those 10 or above .reduce((prev, next) => prev + next, 0); // we sum all the grades 10 or above one by one console.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie below 10 is ignored
详解
以下面的 numbers 数组为例:
const numbers= [0, 1, 2, 3, 4, 5, 6];
Array.prototype.map()
const doubledNumbers = numbers.map(function(n) { return n * 2; }); console.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]
发生了什么?我们对 numbers 调用了 .map()
方法,map方法会遍历数组中的每个元素并将它传给我们的方法。该方法的目标是通过传入的值生成并返回一个新的值以便map可以替换它。
提取出这个函数以便让它更清晰明了:
const doubleN = function(n) { return n * 2; }; const doubledNumbers = numbers.map(doubleN); console.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]
注意:你将会经常碰到该方法与箭头函数结合使用
const doubledNumbers=numbers.map(n=>n* 2); console.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]
numbers.map(doubleN)
生成一个等同于 [0, 2, 4, 6, 8, 10, 12]
的数组 [doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]
。
注意:如果您不需要返回一个新数组并且只想进行具有其他操作的循环,您可以用for / forEach循环替代map。
Array.prototype.filter()
const evenNumbers = numbers.filter(function(n) { return n % 2 === 0; // true if "n" is par, false if "n" isn't }); console.log(evenNumbers); // [0, 2, 4, 6]
注意:与箭头函数结合使用
const evenNumbers=numbers.filter(n=>n% 2 === 0); console.log(evenNumbers); // [0, 2, 4, 6]
我们对 numbers 调用了 .filter()
方法,filter方法会遍历数组中的每个元素并将它传给我们的方法。该方法返回一个布尔值来决定当前元素保留。Filter 会返回一个保留元素的数组。
Array.prototype.reduce()
reduce() 方法的目标是对数组中的每个元素执行一个由您提供的reducer函数,将其结果汇总为单个返回值。如何聚合这些元素取决于你。
const sum = numbers.reduce( function(acc, n) { return acc + n; }, 0 // accumulator variable value at first iteration step ); console.log(sum) // 21
注意:与箭头函数结合使用
const sum=numbers.reduce((acc,n) =>acc+n, 0); console.log(sum) // 21
和 .map
、 .filter
一样, .reduce
别应用在数组上且第一个参数也是一个函数。
但是这次有了一些变化:
-
reduce
接受两个参数
第一个参数是一个函数,每一次迭代时都会被调用。
第二个参数是第一个迭代步骤中累加器变量(acc)的值(阅读下一点来理解)。 - 函数参数
作为.reduce的第一个参数传递的函数有两个参数。第一个(acc )是累加器变量,而第二个参数(n)是当前元素。
累加器变量等于上一次迭代中函数的返回值。在第一此迭代中,acc等于您传给.reduce
的第二个参数。
第一次迭代
acc = 0 因为我们给第二个参数传入0
n = 0 number数组第一个元素
函数返回 acc + n —> 0 + 0 —> 0
第二次迭代
acc = 0 上一步迭代函数的返回值
n = 1 number数组第二个元素
函数返回 acc + n —> 0 + 1 —> 1
第三次迭代
acc = 1 上一步迭代函数的返回值
n = 2 number数组第三个元素
函数返回 acc + n —> 1 + 2 —> 3
第四次迭代
acc = 3 上一步迭代函数的返回值
n = 3 number数组第四个元素
函数返回 acc + n —> 3 + 3 —> 6
[…] 最后一次迭代
acc = 15 上一步迭代函数的返回值
n = 6 number数组最后一个元素
函数返回 acc + n —> 15 + 6 —> 21
最后一个迭代结束, .reduce
返回 21.
相关资源
展开运算符”…”
ES2015已经引入了展开运算符 ...
,用于将可迭代元素(如数组)扩展到一个可以容纳更多元素的地方。
代码示例
const arr1= ["a", "b", "c"]; const arr2= [...arr1, "d", "e", "f"]; // ["a", "b", "c", "d", "e", "f"]
function myFunc(x, y, ...params) { console.log(x); console.log(y); console.log(params) } myFunc("a", "b", "c", "d", "e", "f") // "a" // "b" // ["c", "d", "e", "f"]
const { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; console.log(x); // 1 console.log(y); // 2 console.log(z); // { a: 3, b: 4 } const n = { x, y, ...z }; console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
详解
迭代元素(如数组)
假如我们有以下两个数组:
const arr1= ["a", "b", "c"]; const arr2= [arr1, "d", "e", "f"]; // [["a", "b", "c"], "d", "e", "f"]
arr2第一个元素是一个数组,因为arr1按原样注入arr2。但我们想要的是arr2是一个字母数组。为此,我们可以将arr1的元素展开到arr2中。
使用展开元算符展开
const arr1= ["a", "b", "c"]; const arr2= [...arr1, "d", "e", "f"]; // ["a", "b", "c", "d", "e", "f"]
函数参数展开
在函数参数中,我们可以使用展开运算符将参数注入到一个我们可以循环的数组中。这里已经有一个 arguments
对象在每一个函数中,它的值等同于一个包涵所有传入函数的参数的数组。
function myFunc() { for (var i = 0; i < arguments.length; i++) { console.log(arguments[i]); } } myFunc("Nick", "Anderson", 10, 12, 6); // "Nick" // "Anderson" // 10 // 12 // 6
但是如果说我们希望这个函数能够创建一个包含成绩和平均成绩的新学生。将前两个参数提取到两个单独的变量中,然后将所有分数通过一个可迭代的数组传入,是不是会更方便?
这正是展开运算符允许我们做的事情!
function createStudent(firstName, lastName, ...grades) { // firstName = "Nick" // lastName = "Anderson" // [10, 12, 6] -- "..." takes all other parameters passed and creates a "grades" array variable that contains them const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // computes average grade from grades return { firstName: firstName, lastName: lastName, grades: grades, avgGrade: avgGrade } } const student = createStudent("Nick", "Anderson", 10, 12, 6); console.log(student); // { // firstName: "Nick", // lastName: "Anderson", // grades: [10, 12, 6], // avgGrade: 9,33 // }
注意:createStudent函数很不优雅,因为我们不检查grades.length是否存在或者是否为0。但是这样更容易阅读,所以我没有处理这种情况。
对象属性展开
对于这个,我建议你先阅读上面关于迭代和函数参数的展开运算。
const myObj = { x: 1, y: 2, a: 3, b: 4 }; const { x, y, ...z } = myObj; // object destructuring here console.log(x); // 1 console.log(y); // 2 console.log(z); // { a: 3, b: 4 } // z is the rest of the object destructured: myObj object minus x and y properties destructured const n = { x, y, ...z }; console.log(n); // { x: 1, y: 2, a: 3, b: 4 } // Here z object properties are spread into n
相关资料
- TC39 - Object rest/spread
- Spread operator introduction - WesBos
- JavaScript & the spread operator
- 6 Great uses of the spread operator
Object 属性简写
当你将某个变量赋值给对象某个属性时,如果属性名和变量名相等,你可以这么做:
const x = 10; const myObj = { x }; console.log(myObj.x) // 10
详解
通常(ES2015之前),当你声明一个新的对象字面量并希望将变量当作对象的属性值时,你或许需要写下面这些代码:
const x = 10; const y = 20; const myObj = { x: x, // assigning x variable value to myObj.x y: y // assigning y variable value to myObj.y }; console.log(myObj.x) // 10 console.log(myObj.y) // 20
如你所见,这显得很多余,因为myObj的属性名和要分配给这些属性的变量名相同。
在ES2015中,当变量名和属性名相同时,你可以使用简写:
const x = 10; const y = 20; const myObj = { x, y }; console.log(myObj.x) // 10 console.log(myObj.y) // 20
相关资料
Promises
promise是一个可以从异步函数同步返回的对象 (参考) 。
Promises 可以避免 回调地狱 , 并且它越来越频繁的应用与现代项目中。
代码示例
const fetchingPosts = new Promise((res, rej) => { $.get("/posts") .done(posts => res(posts)) .fail(err => rej(err)); }); fetchingPosts .then(posts => console.log(posts)) .catch(err => console.log(err));
详解
当你发起一个 Ajax请求 时,响应不是同步返回的,因为你想要的资源需要一些时间来才能返回。如果你需要的资源某些资源不可用(404)响应可能永远也不会返回。
为了处理这种情况,ES2015给我们带来了 promise 。Promises可以有三种不同的状态:
- Pending
- Fulfilled
- Rejected
假设我们想使用promises来处理Ajax请求以获取资源X。
创建一个Promise
我们需要先创建一个Promise对象。然后用 jQuery 的 get
方法发起Ajax请求获取X。
const xFetcherPromise = new Promise( // 使用 `new` 关键词创建promise并赋值到一个变量上 function(resolve, reject) { // Promise 构造函数接收一个包含 `resolve`和`reject`两个参数的函数参数 $.get("X") // 发起 Ajax 请求 .done(function(X) { // 一旦请求结束... resolve(X); // ... promise 使用 resolve 返回 X }) .fail(function(error) { // 如果请求失败... reject(error); // ... promise 通过 reject 抛出错误 }); } )
如上例所示,Promise 对象接收一个包含 resolve 和 reject 两个参数的执行函数。这些两个参数都是可调用函数,在被调用时分别将 promise 由 pending 状态转移到 fulfilled 状态和 rejected 状态。
实例创建后,promise处于 pending 状态,并立即执行其执行函数。一旦resolve或reject在执行函数中被调用,promise会调用其相关的处理函数。
Promise 处理函数
要获得promise 的结果(或错误),我们需要依赖于其下例中的方法:
xFetcherPromise .then(function(X) { console.log(X); }) .catch(function(err) { console.log(err) })
如果promise调用成功,则执行 resolve
方法并以其作为参数执行 .then
。
如果失败,则执行 reject
方法并以其作为参数执行 .catch
。
注意:当一个处理函数关联到Promised,该promise已经是fulfilled或rejected状态,处理函数会被调用。所以异步操作和处理函数之间没有竞争条件。
相关资料
- JavaScript Promises for dummies - Jecelyn Yeen
- JavaScript Promise API - David Walsh
- 使用Promise - MDN
- What is a promise - Eric Elliott
- JavaScript Promises: an Introduction - Jake Archibald
- Promise 文档 - MDN
…..积极翻译中…….
以上所述就是小编给大家介绍的《ES6+速查表》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Persuasive Technology
B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95
Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!