是否有一个通用的JavaScript函数来检查变量是否有值,并确保它不是未定义的或空的?我有这个代码,但我不确定它是否涵盖所有情况:
function isEmpty(val){
return (val === undefined || val == null || val.length <= 0) ? true : false;
}
是否有一个通用的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)。。。
其他回答
下面是我的工作。请稍微改变一下,以加快速度
function isEmpty(obj) {
if (!obj) return true;
if (typeof obj == 'number') return false;
else if (typeof obj == 'string') return obj.length == 0;
else if (Array.isArray(obj)) return obj.length == 0;
else if (typeof obj == 'object') return obj == null || Object.keys(obj).length == 0;
else if (typeof obj == 'boolean') return false;
}
我非常喜欢的解决方案:
让我们定义一个空变量为空或未定义,或者如果它有长度,它为零,或者如果是一个对象,它没有键:
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}
function notEmpty(value){
return (typeof value !== 'undefined' && value.trim().length);
}
它还将检查空格(“”)以及以下内容:
null,未定义,NaN,空,字符串(“”),0,false
对于每一个有类似问题的人来说,以下内容非常有用,我在过去的几年里都把它放在了我的图书馆里:
(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/
* http://stackoverflow.com/questions/3215046/differentiating-between-arrays-and-hashes-in-javascript
* 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));
第一个评分最好的答案是错误的。若值未定义,则会在现代浏览器中引发异常。您必须使用:
if (typeof(value) !== "undefined" && value)
or
if (typeof value !== "undefined" && value)