javascript 在 ES6 中作为参数传入 NULL 时,不使用默认参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32725034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:40:28  来源:igfitidea点击:

Passing in NULL as a parameter in ES6 does not use the default parameter when one is provided

javascriptecmascript-6optional-parameters

提问by aus_lacy

Is there a known reason why passing in nullas a parameter in ES6 does not use the default parameter when one is provided?

是否有已知原因,为什么null在 ES6中作为参数传入时不使用默认参数?

function sayHello(name = "World") {
    console.log("Hello, " + name + "!");
}

sayHello("Jim");     // Hello, Jim!
sayHello(undefined); // Hello, World!
sayHello(null);      // Hello, null!

采纳答案by rsp

This is not that obvious

这不是那么明显

I've read some comments of why undefinedis completely different than nulland that's why it explains the current behavior of default parameters.

我已经阅读了一些关于为什么undefined完全不同的评论,这就是null为什么它解释了默认参数的当前行为。

One could argue that explicitly passing undefined should nottrigger the default value substitution because when I have a function:

有人可能会争辩说,显式传递 undefined不应触发默认值替换,因为当我有一个函数时:

const f = (x = 'default') => console.log(x);

I would like it to print "default"when I run it as:

我希望它"default"在运行时打印:

f();

but I would like it to print "undefined"when I explicitly run it as:

但我希望它"undefined"在我明确运行时打印为:

f(undefined);

because otherwise why would I use f(undefined)in the first place? Clearly my intention here is to provide some argument instead of leaving it out.

因为否则我为什么要f(undefined)首先使用?显然,我在这里的意图是提供一些论据,而不是将其排除在外。

Examples to the contrary

相反的例子

Now, consider this function:

现在,考虑这个函数:

const g = (...a) => console.log(JSON.stringify(a));

When I use it as:

当我将其用作:

g();

I get: []

我得到: []

But when I use it as:

但是当我将它用作:

g(undefined);

I get: [null]

我得到: [null]

which clearly demonstrates that:

这清楚地表明:

  1. passing undefinedis not the sameas not passing an argument at all
  2. sometimes nullcan bea default value instead of undefined
  1. 传球undefined不一样的一点都传递一个参数
  2. 有时null可以是默认值而不是undefined

TC39 decision

TC39 决定

Some background on the current behavior of the default parameters can be seen in the July 24 2012 Meeting Notes by TC39:

关于默认参数当前行为的一些背景可以在 2012 年 7 月 24 日的 TC39 会议笔记中看到:

Incidentally, it shows that explicitly passing undefinedoriginally did nottrigger the default value in the first draft and there was a discussion about whether or not it should do that. So as you can see the current behavior was not so obvious to the TC39 members as it now seems to be to people who comment here.

顺便说一句,它表明undefined最初明确通过并没有触发初稿中的默认值,并且讨论了是否应该这样做。因此,正如您所看到的,当前的行为对 TC39 成员来说并不像现在对在这里发表评论的人来说那么明显。

Other languages

其他语言

That having been said, the decision of what should and what should not trigger the default value substitution is completely arbitrary at the end of the day. Even having a separate undefinedand nullcan be though of as quite strange if you think about it. Some language have only undefined(like undefin Perl), some have only null(like Java), some languages use equivalents of falseor an empty list or array for that (like Scheme where you can have an empty list or #f(false) but there is no equivalent of nullthat would be distinct from both an empty list and a false value) and some languages don't even have equivalents of null, falseor undefined(like C which uses integers instead of trueand falseand a NULL pointer which is actually a normal pointer pointing to address 0 - making that address inaccessible even when mapped by any code that tests for null pointers).

话虽如此,决定什么应该和什么不应该触发默认值替换在一天结束时完全是任意的。如果您考虑一下,即使有一个单独的undefined并且null可能会很奇怪。有些语言只有undefined(如undefPerl),有些null语言只有(如 Java),有些语言false为此使用等效项或空列表或数组(如 Scheme,您可以使用空列表或#f(false) 但没有等效项)其中的null一个与空列表和假值都不同)并且某些语言甚至没有null, falseor 的等价物undefined(例如 C 使用整数而不是truefalse和一个 NULL 指针,它实际上是一个指向地址 0 的普通指针——即使在被任何测试空指针的代码映射时也无法访问该地址)。

What you can do

你可以做什么

Now, I can understand your need to substitute default values for null. Unfortunately this is not a default behavior but you can make a simple function to help you:

现在,我可以理解您需要将默认值替换为null. 不幸的是,这不是默认行为,但您可以创建一个简单的函数来帮助您:

const N = f => (...a) => f(...a.map(v => (v === null ? undefined : v)));

Now every time you want defaults substituted for nullvalues you can use it like this. E.g. if you have this function from one of the examples above:

现在,每次您想要用默认值替换null值时,您都可以像这样使用它。例如,如果您从上述示例之一中获得了此功能:

const f = (x = 'default') => console.log(x);

it will print "default"for f()and f(undefined)but not for f(null). But when you use the Nfunction defined above to define the ffunction like this:

它将打印"default"forf()f(undefined)但不是 for f(null)。但是当你使用N上面定义的f函数来定义这样的函数时:

const f = N((x = 'default') => console.log(x));

now f()and f(undefined)but also f(null)prints "default".

现在f()f(undefined)而且还f(null)打印"default"

If you want somewhat different behavior, e.g. substituting default values for empty strings - useful for environment variables that can sometimes be set to empty strings instead of not existing, you can use:

如果您想要一些不同的行为,例如用默认值替换空字符串 - 对于有时可以设置为空字符串而不是不存在的环境变量很有用,您可以使用:

const N = f => (...a) => f(...a.map(v => (v === '' ? undefined : v)));

If you want all falsy values to be substituted you can use it like this:

如果您希望替换所有虚假值,您可以像这样使用它:

const N = f => (...a) => f(...a.map(v => (v || undefined)));

If you wanted empty objects to be substituted you could use:

如果您想替换空对象,您可以使用:

const N = f => (...a) => f(...a.map(v => (Object.keys(v).length ? v : undefined)));

and so on...

等等...

Conclusion

结论

The point is that it's your code and you know what should be the API of your functions and how the default values should work. Fortunately JavaScript is powerful enough to let you easily achieve what you need (even if that is not the default behavior of default values, so to speak) with some higher order function magic.

关键是它是你的代码,你知道你的函数的 API 应该是什么以及默认值应该如何工作。幸运的是,JavaScript 足够强大,可以让您通过一些更高阶的函数魔法轻松实现您所需要的(即使这不是默认值的默认行为,可以这么说)。

回答by doldt

That's just how default parameters are defined in the spec. See MDN: (emphasis mine)

这就是规范中定义默认参数的方式。见MDN:(强调我的)

Default function parameters allow formal parameters to be initialized with default values if no value or undefinedis passed.

如果传递值或未定义,则默认函数参数允许使用默认值初始化形式参数。

nullis neither no value, nor undefined, so it doesn't trigger the default initialization.

null既不是no value也不是undefined,因此它不会触发默认初始化。

回答by taxicala

nullis a value that won't trigger the default value to be used, the default values will be used when the argument is undefined.

null是一个不会触发要使用的默认值的值,当参数为 时将使用默认值undefined