在JavaScript中是否有标准函数来检查null、undefined或空变量?

3053

是否有一种通用的JavaScript函数,可以检查变量是否具有值,并确保它不是undefinednull?我有这段代码,但我不确定它是否涵盖了所有情况:

function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}

6
可能是如何在JavaScript中检查空字符串?的重复问题。 - Dour High Arch
191
提示,永远不要写成(truthy statement) ? true : false;。直接写成(truthy statement);即可。 - David Baucum
11
@GeorgeJempty并不是重复的,因为另一个答案特别提到了“字符串”,而这个问题是关于“变量”的。请注意,此处仅进行翻译,不涉及任何解释或其他内容。 - Madbreaks
4
对于这个问题的任何正确答案完全依赖于你如何定义“空白”。 - Madbreaks
7
@Jay,这并不会影响您代码的执行,只是过于冗长。就像您不会说,“Is are you hungry is true?” 而是 “Are you hungry?”所以在代码中只需使用 if (hungry) … 而不是 if (hungry === true) …。就像所有编码风格一样,这只是个人审美问题。更具体地说,对于 OP 提供的例子,他更冗长地表达了“如果它为真,则为真,如果不为真,则为假”,但如果它为真,则已经是真的。如果它为假,则已经是假的。这相当于说:“如果你饿了,那么你就饿了,如果不饿,那么你就不饿。” - David Baucum
显示剩余11条评论
47个回答

5686

您可以检查变量是否具有真值或假值。这意味着

if (value) {
    // do something..
}

如果value不是以下任何一种值:

  • null
  • undefined
  • NaN
  • 空字符串 ("")
  • 0
  • false

则会被评估为true。以上列表中的所有值在ECMA-/Javascript中均为假值(falsy)。您可以在规范ToBoolean部分找到它们。

此外,如果您不确定一个变量是否存在(也就是说,它是否已经声明),您应该使用typeof运算符进行检查。例如:

if (typeof foo !== 'undefined') {
    // foo could get resolved and it's defined
}
如果您可以确定一个变量至少被声明了,您应该直接检查它是否具有如上所示的"truthy"值。

179
如果传入的值是一个本意是false的布尔值,有时候你想要在没有值的情况下给一个默认值,但如果传入的是false布尔值,则这个方法行不通。 - TruMan1
125
在这种情况下(当您的逻辑决定验证时),您需要编写类似于 if( value || value === false ) 的代码。对于所有假值,我们需要明确地进行验证。 - jAndy
40
除非值是数组,否则“truthy”的解释可能会误导。在这种情况下,我们应该检查value.length != 0以获取非空数组。 - user
20
补充一下,如果你感觉 if 语句结构过于繁琐,可以使用三元运算符来代替,例如:var result = undefined ? "truthy" : "falsy"。或者如果你只是想将其强制转换为布尔值,可以使用 !! 运算符,例如:!!1 // true, !!null // false - KFL
10
请注意,这不会检查仅包含空格字符的字符串。 - Christophe Roussy
显示剩余33条评论

348

检查值是否未定义或为空的冗长方法是:

return value === undefined || value === null;

您也可以使用 == 运算符,但这需要知道所有规则

<code>return value == null; // also returns true if value is undefined
</code>

47
检查是否为nullundefined可以这样做:if (value == null)。注意使用的是强制类型转换的 == 运算符。如果你像这样检查if (value === null || value === undefined),那么你可能忘记了/不知道Javascript如何进行强制类型转换。参考链接:http://webreflection.blogspot.nl/2010/10/javascript-coercion-demystified.html - Christiaan Westerbeek
51
@ChristiaanWesterbeek的意思是arg == nullarg === undefined || arg === null会产生相同的结果。尽管如此,作者认为后一种写法更易读。 - Salman A
17
根据我的经验,“arg == null”相当普遍。 - Bryan Downing
9
与测试可能在作用域中合法的 undefined 不同,使用 return value === (void 0) 更加安全。 - x0n
8
@Sharky,一个未定义的变量和一个未声明的变量是不同的:http://lucybain.com/blog/2014/null-undefined-undeclared/ - Christiaan Westerbeek
显示剩余4条评论

132
function isEmpty(value){
  return (value == null || value.length === 0);
}

这将返回true,对于

undefined  // Because undefined == null

null

[]

""

还有零个参数的函数,因为一个函数的length是它所需的声明参数的数量。

为了禁止后一类情况,您可能希望仅检查空字符串。

function isEmpty(value){
  return (value == null || value === '');
}

检查字符串是否为空或者仅包含空格字符

function isEmpty(value){
  return (value == null || value.trim().length === 0);
}

11
undefined == null but undefined !== null - Ian Boyd
5
这是因为你将 == 与 === 进行比较。这意味着:undefined == null(true) undefined != null(false) undefined === null(false) undefined !== null(true)为了更有帮助地指导人们朝正确的方向前进,最好提供更多信息。可以参考 Mozilla 文档中关于两者区别的内容:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness - Corey Young
1
value.trim() 会在这些值上崩溃: [], {}。 - Jean-Philippe Martin

73

这是最安全的检查方法,我在这里没看到过完全像这样发布的:

if (typeof value !== 'undefined' && value) {
    //deal with value'
};

它将覆盖从未定义的情况,以及以下任何一种情况:

  • null(空)
  • undefined(未定义,与从未定义的参数不同)
  • 0
  • ""(空字符串)
  • false(假)
  • NaN(非数字)

编辑:已更改为严格相等运算符(!==),因为这是目前的标准;)


10
我没有点踩,但是关于严格的相等比较,一般规则是除非你需要隐式类型转换,否则应该使用严格比较。 - J.Steve
4
感谢你的评论,史蒂夫。那条通用规则很好。我只是希望人们能理解为什么要使用其中一个。无论从哪个角度看,人们都会很高兴地向你宣讲“始终始终使用严格模式”,好像这是JavaScript中最重要的事情一样。我见过太多像 if(val !== null) 这样的情况,显然会导致不想要的结果。当存在疑虑时使用严格模式没问题,但最好不要有疑虑。 - guya
7
我认为这里的重点是我们期望typeof运算符返回一个字符串,因此使用严格相等检查在技术上更准确、更具体和更快。所以实际上,没有理由使用宽松比较,而不是反过来。同时,在许多情况下,val !== null是完全有效的 - 我经常这么做。我同意你的非一致性论点,但我认为这个例子并不好。不是想和你过不去。 - Bryan Downing
谢谢你的评论Bryan, 你使用val!== null是因为你知道自己在做什么。 初学者希望在val为false时有一个回退。 但是,val永远不会是null,它将是未定义的。如果他没有听那个“始终始终使用严格模式”的建议,他将减少错误。 我曾经在生产代码中看到过这种情况发生。 typeof始终返回字符串,速度差异将是多余的。 因此,在上述情况下使用严格模式的唯一论据是一致性。 我说过“不需要严格相等”。这并不意味着您不能这样做,或者如果这使您的代码更一致,您可以这样做。 - guya
3
这篇文章之所以值得投票,是因为它在7年之后经过了编辑!尤其是考虑到当时的讨论情况 ;) 你干得好,先生! - rmcsharry

36

我非常喜欢的一个解决方案:

我们可以定义一个空变量是nullundefined,或者如果它的长度为零,则为空,或者如果它是一个对象,则没有键:

function isEmpty (value) {
  return (
    // null or undefined
    (value == null) ||

    // has length and it's zero
    (value.hasOwnProperty('length') && value.length === 0) ||

    // is an Object and has no keys
    (value.constructor === Object && Object.keys(value).length === 0)
  )
}

返回:

  • true: undefined, null, "", [], {}
  • false: true, false, 1, 0, -1, "foo", [1, 2, 3], { foo: 1 }

哇,非常感谢!最终排除了false,这正是我一直在寻找的。否则,我试图修复的代码不仅会删除数组中的空值,还会删除有效的false值,这些值必须在else条件中记录下来。就像if (!value || value === '') { delete a.b[field]; } else { a.b[field] = {val: value, ... }; } - 这是一个非常明显但又令人烦恼的错误 ;) - RAM237

32
看一下新的ECMAScript 空值合并运算符
你可以把这个特性 - ?? 运算符 - 看作是在处理 nullundefined 时“回退”到默认值的一种方式。
let x = foo ?? bar();

再次强调,上述代码等同于以下代码。

let x = (foo !== null && foo !== undefined) ? foo : bar();

3
直到看到这篇文章,我才意识到 nullish coalescing 在处理 0 和空字符串时不会被视为 false,这使得它的用途更加广泛。谢谢! - Joe Sadoski
我喜欢使用 if ((x ?? null) === null) 来检查 nullundefined - Marcos Pereira
同样的思路也适用于 ??=。例如:name ??= 'bob' 等同于 name = (name !== null && name !== undefined) ? name : 'bob'文档:nullish 合并赋值运算符 (??=) - tinystone
这绝对是回答变量是否有赋值的最佳解决方案。然而,对于最初的问题,即变量是否为空,它并不是一个解决方案。他们希望将''和[]都视为空。 - undefined

31

你可能会发现以下函数很有用:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

或在 ES7 中(如有改进请评论)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

结果:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

请注意,绑定运算符(::)并不是ES2016(ES7)或任何后续版本的ECMAScript标准的一部分。它目前仅是一个雏鸟阶段0的提议,旨在引入该语言。作者希望为这个美丽的提议增加支持,以获得皇家认可。


+1 知道 'regexp'、'array' 和 'function' 类型的对象对编程很有帮助。 - Yash
@Vix,为什么ES7版本更好? - GollyJer
这并不是在尝试使用解构赋值和绑定运算符等更易读的方式来表达相同功能。 - Vix
4
请注意,绑定运算符(::)不是 ES2016(ES7)或任何后续版本的 ECMAScript 标准的一部分。目前,它是一个雏鹤阶段 0 的提案,旨在引入该语言中。 - Simon Kjellberg

30

这个条件检查

if (!!foo) {
    //foo is defined
}

你所需要的就是爱。


3
我假设这只是一小段代码。但是 if 已经执行了 falsy 检查,而这只是将其转换为布尔值。它是否能够捕获任何正常的 if(foo) 无法捕获的情况? - Daan van Hulst
2
这非常适合需要内联的情况,例如我需要一个名为active的React属性,在字符串不为空时为true - 如果使用if语句会过于复杂,所以我可以只使用active={!!foo} - Ben Kolya Mansley
20
除非foo为0。 - Gorky
2
更多信息请参见 MDN 上的 双非 (!!)。此外,如果 foo0,则 !!foo 的值为 false - DavidRR
不对!这与原始问题相反的逻辑,是一种测试isEmpty的方法。这将对未定义或空值返回true。但更进一步,这并没有解决0和''是虚假的事实。 - undefined

28

第一个最高评分的答案是错误的。如果值未定义,在现代浏览器中将会抛出异常。你需要使用:

if (typeof(value) !== "undefined" && value)
或者
if (typeof value  !== "undefined" && value)

3
我认为这是错误的,因为(除了空对象/数组)if(value)已经足够。如果值为“undefined”,则“if”条件不会通过。 - Oskar Szura
4
这混淆了未定义的变量(在评估时会引发ReferenceError),这与具有“undefined”值的变量不同。 - Qantas 94 Heavy
2
我在这里得到了同样的错误。如果x,if(!x),if(!!x)如果x未定义,则都会抛出错误。 - shaosh
如果(value === 0),则游戏结束(); - Madbreaks
这个答案也是错误的,因为当value为零时它返回false,这不是op想要的。 - Madbreaks
阅读@Qantas94Heavy的评论,这将澄清这里的混淆。当引用未定义的变量时,我们会得到一个异常。但是在这里,变量已经被定义,只是值没有被定义。 - Ranjith Kumar

21

!检查空字符串(""),null,undefined,false和数字0和NaN。例如,如果一个字符串是空的var name = "",那么console.log(!name)返回true

function isEmpty(val){
  return !val;
}
此函数会在 val 为空、null、未定义、false、数字0或NaN时返回true。 或者 根据您的问题领域,您可以使用类似于 !val!!val 的方式。

这并没有真正说明变量是否为空,因为false和0可以是有效值,而不构成空值。拥有一个isEmpty函数的价值在于确保您期望为空的值返回true。在我看来,null、undefined、NaN和空字符串是有意义的空值。 - Corey Young
19
为什么要使用 isEmpty(val),而不只是简单地用 !val 呢? - Allen Linatoc
由你决定。你可以使用它来提高可读性。否则,如果你认为你所在的团队是更高级的编码人员,那么根据你的问题域,你可以只使用!val!!val - Arif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接