先从阮老师ES6教程的一个事例说起

// 写法一
function m1({x = 0, y = 0} = {}) {
return [x, y];
}

// 写法二
function m2({x, y} = { x: 0, y: 0 }) {
return [x, y];
}

请问这两个的写的有什么区别?一开始看到这个我是蒙的?因为这里将函数的默认值的ES6写法和ES6写法的解构赋值放在了一起。

解释与理清

在这里,函数的参数都变成了对象,而ES6的解构复制就是将利用两个对象的对比来进行赋值进而简化代码

而阮老师给出的答案是

// 函数没有参数的情况
m1() // [0, 0]
m2() // [0, 0]

// x和y都有值的情况
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]

// x有值,y无值的情况
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]

// x和y都无值的情况
m1({}) // [0, 0];
m2({}) // [undefined, undefined]

m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

解决问题的思路

我们解决问题都是从大到小,从简单到复杂,在函数的参数传值比较复杂的情况下也是利用从外到里的看

首先我们看写法一 {x = 0, y = 0} = {}

  • 我们从外到里的看,首先是 调用 传入参数,接着才是判断 是否有参数 如果,那么默认值 即最右边 = 右边的 {} 不会生效 进入下一步 如果 没有 那么就默认值 即最右边 = 右边的 {} 就会成为函数参数的默认值

  • 如果外层的默认值不生效 接着看传入的参数对象内部 { } 是否 符合参数对象 内部默认的 x y两个参数 如果不符合 就会启用内层x y 的默认值 ,要是符合,就利用传入的原值

调用 m1() 首先看外层,没有参数,所以启用默认值即最右边 = 右边的 {} ,那么再看内层,这里面没有符合x y的参数 所以就会启用内层x y的默认值 所以结果为[0,0]

调用 m1({x: 3, y: 8}) 内层外层都不会启用默认值所以为 [3,8]

调用 m1({x: 3}) 外层有 {} 的对象不启用外层默认值,但是内层没有参数y,所以y启用内层默认值结果为[3,0]

调用 m1({}) 外层有 {} 的对象不启用外层默认值,内层无x y,所以启用x y默认值 结果为 [0,0]

调用 m1({z: 3}) 同上

接着我们看写法二 {x, y} = { x: 0, y: 0 }

  • 我们从外到里的看,首先 调用 ,判断 是否有参数 ,没用有就用默认值 { x: 0, y: 0 }

  • 如果外层的默认值不生效 接着看传入的参数对象内部 { } 是否 符合参数对象 内部有 x y两个参数 但是这两个参数没有默认值

调用 m2() 首先看外层,没有参数,所以启用默认值 即最右边 = 右边的 { x: 0, y: 0 },那么结果为[0,0]

调用 m2({x: 3, y: 8}) 内层外层都不会启用默认值所以为[3,8]

调用 m2({x: 3}) 外层有 {} 的对象不启用外层默认值 内层y没有默认值,所以就结果为[3, undefined]

调用 m2({}) 外层有 {} 的对象不启用外层默认值,内层无x y 且x y 无默认值,结果为[undefined, undefined]

调用 m1({z: 3}) 同上


猫仔面
328 声望2 粉丝

chanchun.net