ES6中的函数参数定义

fox*_*fox 11 javascript ecmascript-harmony ecmascript-6

我确信这是相对简单的,我错过了一些明显的东西.我正在阅读Mozilla关于ES6 的教程,他们关于解构章节包含以下模式:

功能参数定义

作为开发人员,我们通常可以通过接受具有多个属性作为参数的单个对象来展示更符合人体工程学的API,而不是强迫我们的API使用者记住许多单个参数的顺序.每当我们想要引用它的一个属性时,我们可以使用解构来避免重复这个单个参数对象:

function removeBreakpoint({ url, line, column }) {   
    // ... 
}
Run Code Online (Sandbox Code Playgroud)

这是Firefox DevTools JavaScript调试器(也在JavaScript-yo dawg中实现)的简化现实代码片段.我们发现这种模式特别令人愉悦.

我不明白这与解构有何关系.您是否允许将对象传递给此函数的想法,只要它包含所有项目,即可以按任意顺序进行,即{ line: 10, column: 20, url: 'localhost' }

如果是这样,那么有什么好处呢

 function removeBreakpoint(params) {   
     // ... 
 }
Run Code Online (Sandbox Code Playgroud)

其中params为与对象url,linecolumn?是否只是强制Javascript在通过显式定义它们时在析构化上下文中使用时验证函数的参数?

T.J*_*der 15

我不明白这与解构有何关系.

removeBreakpoint,你可以使用url,linecolumn直接.removeBreakpoint使用选项对象调用时会发生解构; 该对象的匹配属性被解构为单个参数.

只要它包含所有项目,即{line:10,column:20,url:'localhost'},您是否允许将对象传递给此函数的想法可以按任意顺序排列?

是的,但它不必包含所有项目; 如果没有,那么因为参数是从不存在的对象属性初始化的,所以参数是undefined(除非指定了默认值).

简单的例子证明了解构(Live广告与ES5翻译巴贝尔的REPL):

"use strict";
function removeBreakpoint({ url, line, column }) {   
    console.log("removeBreakpoint:");
    console.log("url: " + url);
    console.log("line: " + line);
    console.log("column: " + column);
}
removeBreakpoint({
  url: "the url",
  line: "the line",
  column: "the column"
});
removeBreakpoint({
  url: "the url",
  line: "the line"
});
Run Code Online (Sandbox Code Playgroud)

输出:

removeBreakpoint:
url: the url
line: the line
column: the column
removeBreakpoint:
url: the url
line: the line
column: undefined

如果是这样,那么有什么好处呢

function removeBreakpoint(params) {   
   // ... 
}
Run Code Online (Sandbox Code Playgroud)

params是一个包含url,line和column的对象?

句法糖.接受选项对象的新语法更简洁和声明,自动化了一个通用模式.将它与默认值(实时复制)组合时,这一点尤为明显:

"use strict";
function removeBreakpoint(
    {                               // <= { starts destructuring arg
        url = "url default",        // <= Default for `url`
        line = "line default",      // <= ...for `line`
        column = "column default"   // <= ...for `column`
    }                               // <= } ends destructuring arg
    = {}                            // <= Default for the options object iself
) {                                 //    (see notes after the code block)
    console.log("removeBreakpoint:");
    console.log(url);
    console.log(line);
    console.log(column);
}
removeBreakpoint({
  url: "the url",
  line: "the line",
  column: "the column"
});
removeBreakpoint({
  url: "the url",
  line: "the line"
});
removeBreakpoint();
Run Code Online (Sandbox Code Playgroud)

输出:

removeBreakpoint:
the url
the line
the column
removeBreakpoint:
the url
the line
column default
removeBreakpoint:
url default
line default
column default

在上面,即使是options对象本身也是可选的,这就是最后一次调用的工作原理:

removeBreakpoint();
Run Code Online (Sandbox Code Playgroud)

如果我们没有给予默认选项对象本身,该呼叫就失败了,因为我们会试图读取属性urlundefined.有时候你想要那样,所以你就不用担心整个选项了.其他时候你没有.


旁注:默认部分选项对象以及整个选项对象的默认情况会导致一种有趣的情况,根据是否给出了选项对象但没有特定选项,您可以使用不同的默认值.根本没有给出任何选项对象,所有都以声明方式完成:Live Copy

"use strict";
function test(
    num,
    {
        foo = "foo default",
        bar = "options given without bar"
    } = {bar: "options not given at all"}
) {
    console.log(num + ": foo = " + foo + ", bar = " + bar);
}
test(1, {foo: "foo value", bar: "options given with bar"});
test(2, {bar: "options given with bar"});
test(3, {});
test(4);
Run Code Online (Sandbox Code Playgroud)

输出:

1: foo = foo value, bar = options given with bar
2: foo = foo default, bar = options given with bar
3: foo = foo default, bar = options given without  bar
4: foo = foo default, bar = options not given at all