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 展开(spread) 到 arr2。
通过展开操作符:
const arr1 = ["a", "b", "c"]; const arr2 = [...arr1, "d", "e", "f"]; // ["a", "b", "c", "d", "e", "f"] 函数剩余参数在函数参数中,我们可以使用 rest 操作符将参数注入到我们可以循环的数组中。这里已经有一个 argument 对象绑定到每个函数上,等同于把数组中的所有参数都传递给函数。
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但是如果说,我们希望创造的是一个包含各科成绩和平均成绩的新学生。将前两个参数提取为两个单独的变量,并把剩下的元素生成一个可迭代的数组是不是更加方便呢?
这正是 rest 操作符允许我们做的事情!
function createStudent(firstName, lastName, ...grades) { // firstName = "Nick" // lastName = "Anderson" // [10, 12, 6] -- "..." 将传递所有剩余参数,并创建一个包含它们的 "grades" 数组变量 const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // 根据 grade 计算平均成绩 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.333333333333334 // }注意: 在这个示例中, createStudent 函数其实并不太好,因为我们并没有去检查 grades.length 是否存在又或者它等于 0 的情况。但是这个例子现在这样写,能够更好的帮助我们理解剩余参数的运作,所以我没有处理上述的这种情况。
对象属性展开对于这一点,我建议你阅读有关 rest 操作符以前的有关迭代和函数参数的相关说明。
const myObj = { x: 1, y: 2, a: 3, b: 4 }; const { x, y, ...z } = myObj; // 这里是对象被解构 console.log(x); // 1 console.log(y); // 2 console.log(z); // { a: 3, b: 4 } // z是对象解构后的剩余部分:myObj 对象除去 x 和 y 属性后剩余部分被解构 const n = { x, y, ...z }; console.log(n); // { x: 1, y: 2, a: 3, b: 4 } // 这里 z 对象的属性展开到 n 中 扩展资源 对象属性简写将变量分配给一个对象属性时,如果变量名称和属性名称相同,你可以执行以下操作:
const x = 10; const myObj = { x }; console.log(myObj.x) // 10 说明通常(ES2015之前)当你声明一个新的 对象字面量 并且想要使用变量作为对象属性值时,你会写这样类似的代码:
const x = 10; const y = 20; const myObj = { x: x, // 将 x 分配给 myObj.x y: y // 将 y 变量给 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 扩展资源 PromisesPromises 是一个可以从异步函数 () 同步返回的对象。
可以使用 Promises 来避免 回调地狱 (callback hell) ,而且它们在现代 JavaScript 项目中越来越频繁地遇到。
简单的代码示例 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 为我们提供了 promises。 Promises 可以有三种不同的状态:
等待中 (Pending)
达成 (Fulfilled)
拒绝 (Rejected)
假设我们希望使用 promises 去进行 Ajax 请求以获取 X 资源。
创建 promise