在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个回答

6

检查默认值

function typeOfVar (obj) {
      return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
function isVariableHaveDefaltVal(variable) {
    if ( typeof(variable) === 'string' ) {  // number, boolean, string, object 
        console.log(' Any data Between single/double Quotes is treated as String ');        
        return (variable.trim().length === 0) ? true : false;
    }else if ( typeof(variable) === 'boolean' ) {
      console.log('boolean value with default value \'false\'');
        return (variable === false) ? true : false;
    }else if ( typeof(variable) === 'undefined' ) {
        console.log('EX: var a; variable is created, but has the default value of undefined.'); 
        return true;
    }else if ( typeof(variable) === 'number' ) { 
        console.log('number : '+variable);
        return (variable === 0 ) ? true : false;
    }else if ( typeof(variable) === 'object' ) {
   //   -----Object-----
        if (typeOfVar(variable) === 'array' && variable.length === 0) {
            console.log('\t Object Array with length = ' + [].length); // Object.keys(variable)
            return true;
        }else if (typeOfVar(variable) === 'string' && variable.length === 0 ) {
            console.log('\t Object String with length = ' + variable.length);
            return true;
        }else if (typeOfVar(variable) === 'boolean' ) {
            console.log('\t Object Boolean = ' + variable);
            return (variable === false) ? true : false;
        }else if (typeOfVar(variable) === 'number' ) {
            console.log('\t Object Number = ' + variable);
            return (variable === 0 ) ? true : false;
        }else if (typeOfVar(variable) === 'regexp' && variable.source.trim().length === 0 ) {
       console.log('\t Object Regular Expression : ');
        return true;
        }else if (variable === null) {
       console.log('\t Object null value');
        return true;
        }
    }
    return false;
}
var str = "A Basket For Every Occasion";
str = str.replace(/\s/g, "-");
//The "g" flag in the regex will cause all spaces to get replaced.

检查结果:

isVariableHaveDefaltVal(' '); // string          
isVariableHaveDefaltVal(false); // boolean       
var a;           
isVariableHaveDefaltVal(a);               
isVariableHaveDefaltVal(0); // number             
isVariableHaveDefaltVal(parseInt('')); // NAN isNAN(' '); - true         
isVariableHaveDefaltVal(null);              
isVariableHaveDefaltVal([]);               
isVariableHaveDefaltVal(/ /);              
isVariableHaveDefaltVal(new Object(''));               
isVariableHaveDefaltVal(new Object(false));            
isVariableHaveDefaltVal(new Object(0)); 
typeOfVar( function() {} );

我使用@Vix的function()来检查对象的类型。
使用instansof关键字
var prototypes_or_Literals = function (obj) {
    switch (typeof(obj)) {
        // object prototypes
        case 'object':
            if (obj instanceof Array)
                return '[object Array]';
            else if (obj instanceof Date)
                return '[object Date]';
            else if (obj instanceof RegExp)
                return '[object regexp]';
            else if (obj instanceof String)
                return '[object String]';
            else if (obj instanceof Number)
                return '[object Number]';

            else
                return 'object';
        // object literals
        default:
            return typeof(obj);
    }   
};
output test «
prototypes_or_Literals( '' ) // "string"
prototypes_or_Literals( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]"        

比较运算符检查 == [数据]。=== [数据,对象类型] JS数字始终存储为双精度浮点数,遵循国际IEEE 754标准。// 数字类型[int,float文字] var int = 77; var float = 77.7; console.log(int.toFixed(10) +'\t'+ float.toFixed(10)); // 对象类型 var number = new Number(77); if (int!= float) console.log('数据不相等'); if (int == number && int!== number) console.log('数据相等且类型不同'); - Yash

5

尝试使用不同的逻辑。您可以使用以下代码来检查四种验证条件,如非空、非空白、非未定义和非零,只需在 JavaScript 和 jQuery 中使用此代码 (!(!(variable)))。

function myFunction() {
    var data;  //The Values can be like as null, blank, undefined, zero you can test

    if(!(!(data)))
    {
        alert("data "+data);
    } 
    else 
    {
        alert("data is "+data);
    }
}

5
如果您正在使用 TypeScript 并且不想考虑“值为 false”的情况,则这是适合您的解决方案:
首先:导入 isNullOrUndefined 方法: import { isNullOrUndefined } from 'util'; 然后:使用 isNullOrUndefined(this.yourVariableName) 来进行判断。
请注意:如下 所述,此方法已被弃用,请使用 value === undefined || value === null 代替。链接

2
我认为这很酷所以我最初取消了投票,但这是一个已经被弃用的Node.js功能。类型定义文件说:/** @deprecated since v4.0.0 - use "value === null || value === undefined" instead. */ - atomictom
@atomictom 我认为这是 typescript 的问题。你能否提供它的文档链接? - BlackBeard
这里:https://nodejs.org/api/util.html#util_util_isnullorundefined_object。另外,“我觉得这很酷,所以我最初点了个赞”,应该是 :)。 - atomictom
1
为什么会废弃这样一个有用的简单东西?天啊。 - ticktock

5

如果你想避免以下任何一个值返回true,可以参考jAndy的回答

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

可能的一种解决方案是以下内容:

function isUsable(valueToCheck) {
    if (valueToCheck === 0     || // Avoid returning false if the value is 0.
        valueToCheck === ''    || // Avoid returning false if the value is an empty string.
        valueToCheck === false || // Avoid returning false if the value is false.
        valueToCheck)             // Returns true if it isn't null, undefined, or NaN.
    {
        return true;
    } else {
        return false;
    }
}

以下是使用方法:

它将按以下方式使用:

if (isUsable(x)) {
    // It is usable!
}
// Make sure to avoid placing the logical NOT operator before the parameter (isUsable(!x)) and instead, use it before the function, to check the returned value.
if (!isUsable(x)) {
    // It is NOT usable!
}

除了这些情况,如果对象数组为空,您可能希望返回false: 您可以按照以下方式操作:
function isEmptyObject(valueToCheck) {
    if(typeof valueToCheck === 'object' && !Object.keys(valueToCheck).length){
        // Object is empty!
        return true;
    } else {
        // Object is not empty!
        return false;
    }
}

function isEmptyArray(valueToCheck) {
    if(Array.isArray(valueToCheck) && !valueToCheck.length) {
        // Array is empty!
        return true;
    } else {
        // Array is not empty!
        return false;
    }
}

如果您想检查所有的空格字符串(" "),可以按照以下方式进行操作:
function isAllWhitespace(){
    if (valueToCheck.match(/^ *$/) !== null) {
        // Is all whitespaces!
        return true;
    } else {
        // Is not all whitespaces!
        return false;
    }
}

注意:如果变量声明为以下任何一种类型,hasOwnProperty 都会返回 true:空字符串、0、false、NaN、null 和 undefined,因此可能不是最好的选择。可以修改该函数以使用它来显示已声明但不可用的情况。

4
可选链操作符提供了一种简化访问连接对象值的方式,当引用或函数可能未定义或为空时使用。
let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls" // detailed address is unknown
  }
};
let customerCity = customer.details?.address?.city;

空值合并运算符可在可选链之后使用,以便在未找到默认值时构建默认值:
let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city

3

如果有类似问题的人来到这里,以下内容非常有效,我已经在我的库中使用了几年:

(function(g3, $, window, document, undefined){
   g3.utils = g3.utils || {};
/********************************Function type()********************************
* Returns a lowercase string representation of an object's constructor.
* @module {g3.utils}
* @function {g3.utils.type}
* @public
* @param {Type} 'obj' is any type native, host or custom.
* @return {String} Returns a lowercase string representing the object's 
* constructor which is different from word 'object' if they are not custom.
* @reference http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
* https://dev59.com/RnA75IYBdhLWcg3wlqIT
* http://javascript.info/tutorial/type-detection
*******************************************************************************/
g3.utils.type = function (obj){
   if(obj === null)
      return 'null';
   else if(typeof obj === 'undefined')
      return 'undefined';
   return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
};
}(window.g3 = window.g3 || {}, jQuery, window, document));

3
var myNewValue = myObject && myObject.child && myObject.child.myValue;

这段代码不会抛出错误。如果myObjectchildmyValue为null,则myNewValue也将为null,不会抛出任何错误。


3
function isEmpty(val){
    return !val;
}

但是这个解决方案有点过度设计了,如果你不想为业务模型的需要后续修改函数,直接在代码中使用会更加简洁:
if(!val)...

3

Code on GitHub

const isEmpty = value => (
  (!value && value !== 0 && value !== false)
  || (Array.isArray(value) && value.length === 0)
  || (isObject(value) && Object.keys(value).length === 0)
  || (typeof value.size === 'number' && value.size === 0)

  // `WeekMap.length` is supposed to exist!?
  || (typeof value.length === 'number'
      && typeof value !== 'function' && value.length === 0)
);

// Source: https://levelup.gitconnected.com/javascript-check-if-a-variable-is-an-object-and-nothing-else-not-an-array-a-set-etc-a3987ea08fd7
const isObject = value =>
  Object.prototype.toString.call(value) === '[object Object]';

穷人的测试
const test = () => {
  const run = (label, values, expected) => {
    const length = values.length;
    console.group(`${label} (${length} tests)`);
    values.map((v, i) => {
      console.assert(isEmpty(v) === expected, `${i}: ${v}`);
    });
    console.groupEnd();
  };

  const empty = [
    null, undefined, NaN, '', {}, [],
    new Set(), new Set([]), new Map(), new Map([]),
  ];
  const notEmpty = [
    ' ', 'a', 0, 1, -1, false, true, {a: 1}, [0],
    new Set([0]), new Map([['a', 1]]),
    new WeakMap().set({}, 1),
    new Date(), /a/, new RegExp(), () => {},
  ];
  const shouldBeEmpty = [
    {undefined: undefined}, new Map([[]]),
  ];

  run('EMPTY', empty, true);
  run('NOT EMPTY', notEmpty, false);
  run('SHOULD BE EMPTY', shouldBeEmpty, true);
};

测试结果:

EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
  Assertion failed: 0: [object Object]
  Assertion failed: 1: [object Map]

很棒的函数,其他所有答案都有多个问题,而你的似乎解决了这些问题,我只希望在编写自己的函数之前能找到它:p。我想你可能会喜欢看看我的工作https://dev59.com/pm035IYBdhLWcg3wSN4G#61350550,我们两个的函数似乎具有完全相同的输出,但我减少了一些代码。如果我漏掉了什么,请告诉我。 - Sean Bannister
你试过我的“穷人测试”吗?我认为我最终在函数中添加了更多的测试,以处理像Map、WeakMap和可能也包括Date、RegExp这样的特殊情况。 你确定你的value.constructor === Object吗?请查看这个 - Pascal Polleunus
是的,我运行了你的测试,感谢那些测试,我们两个函数在这些测试中返回相同的结果。我一直在想,除了这些测试用例之外,我是否漏掉了什么。我相信 value.constructor === Object 是可以的,在 JavaScript 中,IF OR 语句有执行顺序,因此如果前面的语句没有返回 TRUE,那么 OR 语句将不会执行,并且我们已经检查了 Null。实际上,最后一个 OR 语句的唯一目的是检测 {} 并确保它不会为不应该返回 TRUE 的内容返回 TRUE。 - Sean Bannister

2

只使用“nullish coalescing”检查undefined和null

if ((myVariable ?? undefined) !== undefined) {
    // handle myVariable has a value, including 0 or ""
}
else {
    // handle undefined or null only
}

从Chrome控制台

{const x=undefined; (x ?? undefined) !== undefined}
false

{const x=null; (x ?? undefined) !== undefined}
false

{const x=0; (x ?? undefined) !== undefined}
true

{const x=""; (x ?? undefined) !== undefined}
true

{const x={}; (x ?? undefined) !== undefined}
true

{const x=[]; (x ?? undefined) !== undefined}
true

{const x="a"; (x ?? undefined) !== undefined}
true

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