ES6 中的函数参数定义

IT技术 javascript ecmascript-6 ecmascript-harmony
2021-03-11 20:39:10

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

功能参数定义

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

function removeBreakpoint({ url, line, column }) {   
    // ... 
}

这是来自 Firefox DevTools JavaScript 调试器(也在 JavaScript 中实现)的真实世界代码的简化片段——哟 dawg。我们发现这种模式特别令人愉悦。

我不明白的是这与解构有何关系。是否允许将对象传递给这个函数的能力,只要它包含所有项目,它就可以是任意顺序的,即{ line: 10, column: 20, url: 'localhost' }

如果是这样,那么比之类的东西有什么好处

 function removeBreakpoint(params) {   
     // ... 
 }

其中params为与对象urllinecolumn这个想法是否只是通过显式定义在解构上下文中使用时强制 Javascript 验证函数的参数?

1个回答

我不明白的是这与解构有何关系。

removeBreakpoint,你可以使用urllinecolumn直接。removeBreakpoint使用选项对象调用时会发生解构该对象的匹配属性被分解为单独的参数。

是否允许将一个对象传递给这个函数的能力,只要它包含所有项目,它就可以是任意顺序,即 { line: 10, column: 20, url: 'localhost' } ?

是的,但它不必包含所有项目;如果不是,则由于参数是从不存在的对象属性初始化的,因此该参数是undefined(除非指定了默认值)。

演示解构的简单示例(Babel的 REPL带有 ES5 翻译的Live Copy):

"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"
});

输出:

移除断点:
网址:网址
线:线
列:列
移除断点:
网址:网址
线:线
列:未定义

如果是这样,那么比之类的东西有什么好处

function removeBreakpoint(params) {   
   // ... 
}

其中 params 是一个带有 url、line 和 column 的对象?

语法糖。接受选项对象的新语法更加简洁和声明性,自动化了一个常见的模式。当您将其与默认值 ( Live Copy )结合使用时,这一点尤为明显

"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();

输出:

移除断点:
网址
线
专栏
移除断点:
网址
线
列默认值
移除断点:
网址默认
线路默认值
列默认值

在上面,甚至选项对象本身也是可选的,这就是为什么最后一个调用有效:

removeBreakpoint();

如果我们没有给予默认选项对象本身,该呼叫就失败了,因为我们会试图读取属性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);

输出:

1: foo = foo 值,bar = 用 bar 给出的选项
2: foo = foo 默认值,bar = 与 bar 一起给出的选项
3: foo = foo 默认值,bar = 不带 bar 的选项
4:foo = foo 默认值,bar = 根本没有给出选项