作为ES6中的参数传递NULL作为参数,在提供的时候不使用默认参数 [英] Passing in NULL as a parameter in ES6 does not use the default parameter when one is provided

查看:286
本文介绍了作为ES6中的参数传递NULL作为参数,在提供的时候不使用默认参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一个已知的原因,为什么在ES6中作为参数传递 null 不提供默认参数?

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

sayHello(Jim); //你好,吉姆!
sayHello(undefined); // 你好,世界!
sayHello(null); // Hello,null!


解决方案

这不是很明显的



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



可以认为明确传递未定义的不应该触发默认值替换,因为当我有一个功能:

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

我想要打印default当我运行它:

  f(); 

但我想要打印undefined当我明确地运行它为:

  f(undefined); 

否则为什么我会使用 f(undefined)在第一位?显然,我的意图是提供一些论据,而不是把它留下来。



相反的例子



现在考虑这个功能:

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

当我使用它作为:

 克(); 

我得到: []



但是当我使用它作为:

  g(undefined); 

我得到: [null] p>

清楚地表明:


  1. 传递 undefined 不一样,因为没有传递参数

  2. 有时 null strong>可以一个默认值,而不是未定义



TC39决定



TC39的2012年7月24日会议笔记可以看到有关这些默认参数的一些背景:





顺便提一句,它表明,明确地通过 undefined 原来没有触发初稿中的默认值,有人讨论是否应该做这件事帽子。所以你可以看到目前的行为对于TC39成员来说并不那么明显,因为现在似乎是在这里发表评论的人。



其他语言

$已经说过,在一天结束时,什么应该和什么不应该触发默认值替换的决定是完全任意的。即使有一个单独的未定义 null 也可以是非常奇怪的,如果你考虑。某些语言在Perl中只有 undefined (如 undef ),有些语言只有 null (如Java),一些语言使用等价的 false 或一个空的列表或数组(如Scheme,您可以使用空列表或 #f (false),但是没有等价于 null ,这与空列表和假值都不同)而某些语言甚至没有等价的 null false undefined (如C使用整数而不是 true false 和一个实际上是一个正常的NULL指针指向地址0的指针 - 即使通过任何测试空指针的代码进行映射也可以访问该地址。)



您可以做什么



现在,我可以理解你需要替换 null 的默认值。不幸的是,这不是默认行为,但是您可以使用简单的函数来帮助您:

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

现在,每次要默认代替 null 值可以这样使用。例如。如果你有以上一个例子的这个函数:

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

它将打印default code> f() f(未定义)但不适用于 f(null)。但是当您使用上面定义的 N 函数定义 f 函数时,如下所示:

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

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



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

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

如果你想要所有的falsy值替代,你可以这样使用:

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

如果你想要空对象被替代,你可以使用:

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

等等...



结论



关键是这是你的代码,你知道应该是你的函数的API以及默认值的工作原理。幸运的是,JavaScript具有足够的强大功能,可以让您轻松实现所需的功能(即使这不是默认值的默认行为,可以这么说)具有一些更高级的功能魔术。


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

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

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

解决方案

This is not that obvious

I've read some comments of why undefined is completely different than null and that's why it explains the current behavior of default parameters.

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

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

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

f();

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

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.

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]

which clearly demonstrates that:

  1. passing undefined is not the same as not passing an argument at all
  2. sometimes null can be a default value instead of undefined

TC39 decision

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

Incidentally, it shows that explicitly passing undefined originally did not trigger 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.

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 undefined and null can be though of as quite strange if you think about it. Some language have only undefined (like undef in Perl), some have only null (like Java), some languages use equivalents of false or 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 null that would be distinct from both an empty list and a false value) and some languages don't even have equivalents of null, false or undefined (like C which uses integers instead of true and false and 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).

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:

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

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

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 N function defined above to define the f function like this:

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

now f() and f(undefined) but also f(null) prints "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.

这篇关于作为ES6中的参数传递NULL作为参数,在提供的时候不使用默认参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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