
这是一个在函数签名中使用解构(destructuring)的例子。
解构或许是JavaScript在ES6规范中最大的句法变化。虽然这种新语法对于许多长期JavaScript程序员来说似乎很奇怪,但一旦你能够充分理解它,使用它将会非常强大。
如果你还没有熟悉的解构,它是一种将对象字面量或数组字面量同时与多个赋值语句建立映射的能力。例如:
解构可以使用数组语法,将右边数组中的每个值赋值给左边数组中对应位置的变量。
//数组的解构
let [a,b,c] = [1,2,3];
console.log(a,b,c) // 1, 2, 3
然而,更常见的是,它可以与对象字面量一起使用,以得到要用作变量的对象的属性。
//对象字面量的解构
//属性名称必须相同
let {x,y,z} = {x: 10, y: 20, z: 30};
console.log(x,y,z); //10, 20, 30
注意 - 在上述对象字面量的例子里,属性名称必须相同。和数组的例子不同的是,在这里位置的顺序并不重要。
如果你想在解构时重命名一些属性,你可以在解构的左侧使用keyName:newKeyName这个语法。
//如果你想重命名属性...
let {x:newX,y:newY,z:newZ} = {x: 10, y: 20, z: 30};
console.log(newX,newY,newZ); //10, 20, 30
第一眼看上去,这似乎是赋值语句的一些语法糖,但是它更多的是在解构的同时将默认值赋给变量的能力。
let {x = 5, y = 8, z = 13} = {x: 10, y: 20};
console.log(x,y,z); //10, 20, 13
这是相当重要的。比如说赋值表达式的右边不是对象字面量,而是应用程序另一部分的函数调用。有一天,一个开发人员出现了,他在另一个函数中实现了一个短路返回语句,这将导致你的调用得不到预期的响应。因此,能够在赋值时设置默认值,可以更容易地保护代码。

解构函数的参数
当您将一个参数传递给函数时,在该函数开始执行之前,它将你传入的参数分配给函数签名中相应的参数。因为它是一个赋值语句,这意味着我们可以用解构在一个函数内分配参数值!
//解构分配参数
let myFunc = function({x,y,z}) {
console.log(x,y,z);
};
myFunc({x:10,y:20,z:30}); //10 20 30
如前所示,我们也可以将在解构时重命名我们的键。
//你可以和之前一样重命名它们
myFunc = function({x:newX,y:newY,z:newZ}) {
console.log(newX,newY,newZ);
};
myFunc({x:10,y:20,z:30}); //10 20 30
最后,我们可以对解构语句中个别的键或者整个语块本身指定默认值。
//无论是对单个值还是整个对象设定默认值都能够起作用
myFunc = function({x = 5,y = 8,z = 13} = {x:1,y:2,z:3}) {
console.log(x,y,z);
};
myFunc(); //1 2 3 (命中对象字面量默认值)
myFunc({}); //5 8 13 (命中默认值)
虽然这段代码看起来有点乏味,但它能阻止我们检查每一个传入的参数是否存在。
命名参数和可选参数
如果你还记得结解构时分配默认值时将第一个例子,结合我们在最后一节中了解到的内容,你可能知道我要讲什么了。如果你能解构函数的参数,并且你可以在解构时指定默认值,再加上解构过程中对象字面量的名称必须匹配,这意味着在你的函数签名中可以有命名参数和可选参数!(只要你用解构)。下面是一个例子:
let myFunc = function({x = 5,y = 8,z = 13} = {}) {
console.log(x,y,z);
};
myFunc({y:15,x:10,a:1}); //10 15 13

结论
希望这篇文章的标题不是太误导人。 虽然我们在Javascript中还没有真正的命名和可选参数,就像C#一样,我刚刚展示了一种使用ES6解构来获取功能上等同的行为的方法。 虽然我没有预见到这种替换位置参数的模式,但是在对服务器进行网络调用时,对于promise的回调的情况下,这是非常有用的。 你可以使用本文中描述的模式来明确定义您期望接收的内容,并为这些值设置默认值,而不是希望网络调用返回您正期待的功能。