ES6 中的函数参数定义 [英] Function parameter definitions in ES6

查看:23
本文介绍了ES6 中的函数参数定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<块引用>

功能参数定义

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

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

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

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

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

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

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

解决方案

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

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

<块引用>

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

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

演示解构的简单示例(实时复制和 ES5 翻译 Babel 的 REPL):

"使用严格";函数 removeBreakpoint({ url, line, column }) {console.log("removeBreakpoint:");console.log("url:" + url);console.log("line:" + line);console.log("列:" + 列);}移除断点({网址:网址",线:线",列:列"});移除断点({网址:网址",线:线"});

输出:

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

<块引用>

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

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

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

语法糖.接受选项对象的新语法更加简洁和声明性,自动化了一个常见的模式.当您将其与默认值(实时复制):

"使用严格";函数删除断点({//<= { 开始解构 argurl = "url default",//<= `url` 的默认值line = "line default",//<= ...for `line`column = "column default"//<= ...for `column`}//<= } 结束解构 arg= {}//<= 选项对象本身的默认值) {//(见代码块后面的注释)console.log("removeBreakpoint:");控制台日志(网址);控制台日志(行);控制台日志(列);}移除断点({网址:网址",线:线",列:列"});移除断点({网址:网址",线:线"});删除断点();

输出:

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

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

removeBreakpoint();

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

<小时>

旁注:默认选项对象的部分以及单独的整个选项对象的能力导致了一种有趣的情况,您可以根据是否给定选项对象具有不同默认值但没有特定的选项与根本没有给出选项对象,所有这些都是以声明方式完成的:实时复制

"使用严格";功能测试(数,{foo = "foo 默认",bar = "不带 bar 的选项"} = {bar:根本没有给出选项"}){console.log(num + ": foo = " + foo + ", bar = " + bar);}test(1, {foo: "foo value", bar: "options given with bar"});test(2, {bar: "options given with bar"});测试(3,{});测试(4);

输出:

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

I'm sure that this is relatively straightforward and that I'm missing something obvious. I'm reading through Mozilla's tutorials on ES6, and their chapter on destructuring contains the following pattern:

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.

What I don't understand is how this relates to destructuring. 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' }?

If so, what is the benefit over something like

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

where params is an object with url, line, and column? Is the idea just that you force Javascript to validate a function's parameters when used in a destructured context by explicitly defining them?

解决方案

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

Within removeBreakpoint, you can use url, line, and column directly. The destructuring happens when removeBreakpoint is called with an options object; that object's matching properties are destructured into individual arguments.

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' }?

Yes, but it doesn't have to contain all the items; if it doesn't, then since the argument is initialized from an object property that doesn't exist, the argument is undefined (unless a default value is specified).

Simple example demonstrating the destructuring (Live Copy with ES5 translation on Babel's 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"
});

Output:

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

Output:

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

If we hadn't given a default for the options object itself, that call would have failed because we'd be trying to read the property url of undefined. Sometimes you want that, and so you'd leave the overall option off. Other times you don't.


Side note: The ability to default parts of the options object and also, separately, the entire options object leads to an interesting situation where you can have different defaults depending on whether an options object was given but didn't have a specific option vs. no options object being given at all, all done declaratively: 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);

Output:

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

这篇关于ES6 中的函数参数定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆