javascript - ES6 中的函数参数定义

标签 javascript ecmascript-6 ecmascript-harmony

我确信这相对简单,而且我遗漏了一些明显的东西。我正在通读 Mozilla's tutorials在 ES6 上,以及它们的 chapter on destructuring包含以下模式:

FUNCTION PARAMETER DEFINITIONS

As developers, we can often expose more ergonomic APIs by accepting a single object with multiple properties as a parameter instead of forcing our API consumers to remember the order of many individual parameters. We can use destructuring to avoid repeating this single parameter object whenever we want to reference one of its properties:

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

This is a simplified snippet of real world code from the Firefox DevTools JavaScript debugger (which is also implemented in JavaScript—yo dawg). We have found this pattern particularly pleasing.

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

如果是这样,相比于类似的东西有什么好处

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

其中 params 是一个包含 urllinecolumn 的对象?这个想法只是你通过显式定义它们来强制 Javascript 在解构上下文中使用时验证函数的参数吗?

最佳答案

What I don't understand is how this relates to destructuring.

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

Is the idea that you permit the ability to pass an object into this function that can be in arbitrary order as long as it contains all items, i.e. { line: 10, column: 20, url: 'localhost' }?

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

演示解构的简单示例(Live Copy with ES5 translationBabel 的 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"
});

输出:

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

If so, what is the benefit over something like

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

where params is an object with url, line, and column?

Syntactic sugar. The new syntax for accepting options objects is more concise and declarative, automating a common pattern. This is particularly apparent when you combine it with default values (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:
the url
the line
the column
removeBreakpoint:
the url
the line
column default
removeBreakpoint:
url default
line default
column default

In the above, even the options object itself is optional, which is why the last call works:

removeBreakpoint();

如果我们没有为选项对象本身提供默认值,该调用将失败,因为我们将尝试读取 undefined 的属性 url。有时您想要那个,所以您会关闭整个选项。其他时候你不需要。


旁注:默认部分选项对象以及单独的整个选项对象的能力会导致一个有趣的情况,您可以根据是否给定选项对象而拥有不同默认值但没有特定选项 vs. 根本没有给出任何选项对象,所有这些都是声明式完成的: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 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

关于javascript - ES6 中的函数参数定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30862988/

相关文章:

javascript - Prototype.js 类系统的替代品

javascript - 按嵌套键对数组进行分组

javascript - ReactJS 从 map 中唯一选择一个元素

javascript - 如何对对象中特定键的所有值求和?

javascript - 为什么我无法从命令行通过 "node --harmony test.js"启动和谐模式?

javascript - 使用node.js、nodeunit 和 ES6/Harmony

JavaScript 对象关系

javascript - "in"运算符如何处理非字符串键?

javascript - Babel 没有将 ES6 转译为 ES5

javascript - Yield 显示语法错误;在 javascript 中缺失;