29

这是检查函数中缺少参数的正确方法吗?这适用于所有浏览器吗?IE怎么样?

function getName(name){
    name = name != null ? name : "default";
    return name;
}
4

4 回答 4

61

检查参数的方式取决于您传递给函数的信息类型,以及您希望函数如何处理极端情况。

在大多数情况下,您可以使用:

...
bar = bar || ...default value here...
...

但是,当您想要传递虚假值(false, 0, NaN, '', undefined, null)时可能会出现问题:

function foo(bar) {
  bar = bar || 5
  console.log(bar)
}

foo()          // 5
foo(undefined) // 5
foo(null)      // 5
foo(1)         // 1
foo(0)         // 5, probably not what you wanted

相反,您可以检查undefined

...
if (bar == undefined) {
    bar = 5
}
...

...但是使用松散检查允许nullundefined被覆盖(null == undefined):

function foo(bar) {
  if (bar == undefined) {
      bar = 5
  }
  console.log(bar)
}

foo()          // 5
foo(undefined) // 5
foo(null)      // 5
foo(1)         // 1

因此,===通常首选严格的相等比较 ( ) ( null !== undefined):

function foo(bar) {
  if (bar === undefined) { 
      bar = 5
  }
  console.log(bar)
}

foo()          // 5
foo(undefined) // 5
foo(null)      // null
foo(1)         // 1

ES2015 引入了默认参数,本质上等同于严格检查undefined

function foo(bar = 5) {
  console.log(bar)
}

foo()          // 5
foo(undefined) // 5
foo(null)      // null
foo(1)         // 1

This could lead to trouble if you need to know whether undefined was passed as a parameter.

If you want to be absolutely certain that you're not passing up an argument that was provided, you can check the number of arguments passed to the function:

...
if (arguments.length < 1) {
  bar = 5
}
...

Which means that you can successfully pass undefined as an argument while also choosing to use a different default:

function foo(bar) {
  if (arguments.length < 1) {
    bar = 5
  }
  console.log(bar)
}

foo()          // 5
foo(undefined) // undefined
foo(null)      // null
foo(1)         // 1


If you have multiple parameters, you may want to use multiple defaults. I've recently found a use case for fallthrough on a switch statement, although the utility is questionable:

function foo(bar, baz, fizz, buzz) {
  switch (arguments.length) {
    case 0:
      bar = 1;
      //continue; might as well point out that implicit fall-through is desired
    case 1:
      baz = 2;
      //continue;
    case 2:
      fizz = 3;
      //continue;
    case 3:
      buzz = 4;
      //continue;
  }
  console.log(bar, baz, fizz, buzz)
}

foo()               // 1 2 3 4
foo(10)             // 10 2 3 4
foo(10, 20)         // 10 20 3 4
foo(10, 20, 30)     // 10 20 30 4
foo(10, 20, 30, 40) // 10 20 30 40

于 2012-10-03T19:17:12.440 回答
24

你可以做:

name = name || 'default';

这表示如果name未定义或虚假(null, 0, "", false, {}, []),请将其设置为"default".

js(h|l)int 会抱怨它,但它至少可以追溯到 IE7。它根本不是无效代码,也不是依赖于一些未记录的行为。

于 2012-10-03T19:08:34.917 回答
9

正确的检查方法是

if (typeof name === "undefined") {
    // ...
}

当然,调用者仍然可以通过调用来“愚弄”您getName(undefined),当提供了参数但检查仍会将其标记为未提供时。但这确实是一种病态的情况。

于 2012-10-03T19:08:23.123 回答
0

是的,这适用于所有浏览器,但如果您想查看它是否已定义,您可以使用:

function getName(name){
   name = typeof(name) !== "undefined" ? name : "default";
   return name;
}
于 2012-10-03T19:09:16.553 回答