是否有一个通用的JavaScript函数来检查变量是否有值,并确保它不是未定义的或空的?我有这个代码,但我不确定它是否涵盖所有情况:

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

当前回答

真空度

我不建议尝试定义或使用计算整个世界中任何值是否为空的函数。“空”到底意味着什么?如果我让human={name:‘bob’,gast:‘empty’},isEmpty(human)是否应该返回true?如果我让reg=new RegExp('');,isEmpty(reg)是否应返回true?isEmpty([null,null,null,null])怎么样?这个列表只包含空,所以列表本身是空的吗?我想在这里提出一些关于javascript中的“真空性”(一个故意模糊的词,以避免预先存在的关联)的注释,并且我想指出,javascript值中的“空洞性”永远不应该被笼统地处理。


真实/虚假

为了决定如何确定值的“空洞性”,我们需要适应javascript内置的固有感觉,即值是“真实的”还是“虚假的”。自然,null和undefined都是“假的”。不那么自然的是,数字0(除了NaN之外没有其他数字)也是“假”的。最不自然的是:“”是假的,但[]和{}(以及new Set()和new Map())是真的——尽管它们看起来都一样空洞!


空与未定义

还有一些关于空和未定义的讨论——我们真的需要这两者来表达程序中的空洞吗?我个人避免在代码中出现undefined。我总是用null表示“空虚”。然而,我们再次需要适应javascript对null和undefined的区别的固有感觉:

尝试访问不存在的属性时,未定义调用函数时省略参数会导致该参数接收到未定义的:

设f=a=>a;控制台日志(f('hi'));console.log(f());

具有默认值的参数仅在给定未定义而非空时接收默认值:

设f=(v='hello')=>v;console.log(f(null));console.log(f(未定义));

对我来说,空是空虚的一个明确的能指;“本可以填写的内容故意留空”。

真正的undefined是一个必要的复杂因素,它允许一些js特性存在,但在我看来,它应该永远留在幕后;没有直接交互。例如,我们可以将undefined看作javascript实现默认函数参数的机制。如果不向函数提供参数,它将收到一个undefined值。如果函数参数最初设置为undefined,则默认值将应用于该参数。在这种情况下,undefined是默认函数参数的关键,但它仍停留在后台:我们可以实现默认参数功能,而无需引用undefined:

这是一个错误的默认参数实现,因为它直接与undefined交互:

let fnWithDefaults = arg => {
  if (arg === undefined) arg = 'default';
  ...
};

这是一个很好的实现:

let fnWithDefaults = (arg='default') => { ... };

这是接受默认参数的坏方法:

fnWithDefaults(undefined);

只需执行以下操作:

fnWithDefaults();

顺便问一下:您是否有一个具有多个参数的函数,并且您希望在接受其他参数的默认值的同时提供一些参数?

例如。:

let fnWithDefaults = (a=1, b=2, c=3, d=4) => console.log(a, b, c, d);

如果您想为a和d提供值并接受其他值的默认值,该怎么办?这似乎是错误的:

fnWithDefaults(10, undefined, undefined, 40);

答案是:重构fnWithDefaults以接受单个对象:

let fnWithDefaults = ({ a=1, b=2, c=3, d=4 }={}) => console.log(a, b, c, d);
fnWithDefaults({ a: 10, d: 40 }); // Now this looks really nice! (And never talks about "undefined")

非通用真空度

我认为,真空永远不应该以一种通用的方式来处理。相反,在确定数据是否空洞之前,我们应该始终严格获取有关数据的更多信息-我主要通过检查我处理的数据类型来做到这一点:

让isType=(value,Cls)=>{//有意使用松散比较运算符检测到`null`//和“undefined”,没有别的!返回值!=null&&Object.getPrototypeOf(值).cconstructor==Cls;};

注意,此函数忽略继承-它希望值是Cls的直接实例,而不是Cls子类的实例。我避免实例化的原因有两个:

([]instanceof Object)===true(“数组是一个对象”)(“”instanceof String)===false(“字符串不是字符串”)

注意,Object.getPrototypeOf用于避免(模糊的)边缘情况,例如let v={constructor:String};isType函数仍然正确返回isType(v,String)(false)和isType(v,Object)(true)。

总之,我建议使用isType函数以及以下提示:

最小化未知类型的代码处理值的数量。例如,对于v=JSON.parse(someRawValue);,我们的v变量现在是未知类型。我们应该尽早限制我们的可能性。最好的方法是要求特定类型:例如,如果(!isType(v,Array))抛出新错误(“预期数组”);-这是一种非常快速且富有表现力的方法,可以消除v的泛型性质,并确保它始终是一个数组。但有时,我们需要允许v具有多种类型。在这些情况下,我们应该尽早创建v不再通用的代码块:

if(isType(v,String)){/*v在这个块中不是通用的-它是一个字符串*/}否则如果(isType(v,Number)){/*v在这个块中不是通用的-它是一个数字*/}否则if(isType(v,Array)){/*v在这个块中不是通用的,它是一个数组*/}其他{抛出新错误(“预期的字符串、数字或数组”);}

始终使用“白名单”进行验证。如果您需要一个值,例如字符串、数字或数组,请检查这3种“白色”可能性,如果这3种可能性都不满足,则抛出错误。我们应该能够看到,检查“黑色”可能性不是很有用:假设我们写if(v==null)throw new Error('null value rejected');-这对于确保空值不通过非常有用,但是如果一个值通过了,我们仍然对它一无所知。通过这个空检查的值v仍然是非常通用的-它不是空!黑名单很难消除共性。除非值为空,否则不要考虑“空值”。相反,考虑“真空的X”。本质上,永远不要考虑做if(isEmpty(val)){/*…*/}-无论isEmpty函数是如何实现的(我不想知道…),它都没有意义!而且太普通了!真空度只能在了解val类型的情况下计算。真空度检查应如下所示:“字符串,无字符”:if(isType(val,String)&&val.length==0)。。。“一个对象,带0个道具”:if(isType(val,Object)&&Object.entries(val).length==0)。。。“数字,等于或小于零”:if(isType(val,number)&&val<=0)。。。“一个数组,没有项目”:if(isType(val,Array)&&val.length==0)。。。唯一的例外是使用null表示某些功能。在这种情况下,说“真空值”很有意义:如果(val==null)。。。

其他回答

对于我的案例,我尝试了if null,“”!变量,但它不起作用。

查看下面的代码以从html字段获取文本

var status=$(this).text(); //for example (for my case)

如果状态变量中没有值(没有文本),我试图将值“novalue”设置为状态变量。

以下代码有效。

if(status == false)
{
   status='novalue';
} 

当没有找到satus变量的文本时,上面的代码将“novalue”分配给状态变量

您可以使用零合并运算符??检查空值和未定义值。参见MDN文档

null ?? 'default string'; // returns "default string"

0 ?? 42;  // returns 0

(null || undefined) ?? "foo"; // returns "foo"

这将检查不确定嵌套的变量是否未定义

function Undef(str) 
{
  var ary = str.split('.');
  var w = window;
  for (i in ary) {
    try      { if (typeof(w = w[ary[i]]) === "undefined") return true; }
    catch(e) { return true; }
  }
  return false;
}

if (!Undef("google.translate.TranslateElement")) {

上面检查Google翻译函数TranslateElement是否存在。这相当于:

if (!(typeof google === "undefined" 
 || typeof google.translate === "undefined" 
 || typeof google.translate.TranslateElement === "undefined")) {

您可以始终使用loadash函数,例如_.isNil或_.isUndefined。它们非常容易使用。

对于我的用例,大多数现有答案都失败了,如果将函数分配给变量或返回NaN,则大多数答案返回为空。帕斯卡的回答很好。

这是我的实现,请测试并让我知道,如果你发现了什么。你可以在这里看到我是如何测试这个函数的。

function isEmpty(value) {
  return (
    // Null or undefined.
    (value == null) ||
    // Check if a Set() or Map() is empty
    (value.size === 0) ||
    // NaN - The only JavaScript value that is unequal to itself.
    (value !== value) ||
    // Length is zero && it's not a function.
    (value.length === 0 && typeof value !== "function") ||
    // Is an Object && has no keys.
    (value.constructor === Object && Object.keys(value).length === 0)
  )
}

退货:

true:undefined,null,“”,[],{},NaN,new Set()//false:true,false,1,0,-1,“foo”,[1,2,3],{foo:1},函数(){}