[转载]在 JavaScript 中判断“空值”
http://lync.in/check-empty-value-in-javascript/
有时候我们会遇到这样的情况:在一些前端控件要提交数据到服务器端的数据验证过程中,需要判断提交的数据是否为空。如果是普通表单的字符串数据,只需要在 trim
后判断 length
即可,而这里需要的数据可以是各种不同的类型(数字、字符串、数组、对象等等),通过 JSON.stringify(data)
进行序列化后再传递。
在这里定义如下的数据值为“空值”:
- undefined
- null
- 空字符串及纯空白字符串:''、' ' 等。
- 空数组:[]
- 空对象:{}
对于除此以外的数据值,均认为不为空。
其中 null
和 undefined
很容易识别,但对于其他类型,我们须要得到其数据类型才能用相应的方法去检测数据是否为空。最容易想到的方法就是利用 typeof
操作符:
1 2 3 |
if(typeof data === 'number') {
//deal with numbers
}
|
但 typeof
返回的类型字符串只有 'object'、'function'、'number'、'boolean'、'string'、'undefined' 这六种,很多原生对象如 Date、RegExp 对象无法与用 {} 创建的对象进行区分。另外,typeof
对于一些基本数据类型如 (String、Number、Boolean) 与其对应的基本包装类型数据会分别返回不同值,如:
1 2 3 4 5 6 |
console.log(typeof false); //'boolean'
console.log(typeof new Boolean(false)); //'object'
console.log(typeof 1); //'number'
console.log(typeof new Number(1)); //'object'
console.log(typeof ''); //'string'
console.log(typeof new String('')); //'object'
|
这对我们的判断也有一定的影响。
用 instanceof
?这只能判断对象,而且存在多 frame 时多个同类对象不共享 prototype 的问题,从其他 frame 中取得的对象无法正确判断。
还好,还有一个最简单也最可靠的方法:Object.prototype.toString
。对于不同类型的数据,这个方法可以返回 '[object Object]'、'[object Array]'、'[object String]' 这样的字符串,非常方便判断。需要注意的是,在 IE8 及其以下浏览器中,这个方法对于 null
、undefined
、window
等都会返回 '[object Object]',不过还好,这并不影响我们使用它判断空对象。
下面直接上代码,说明就看注释吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// with jQuery
var isEmptyValue = function(value) {
var type;
if(value == null) { // 等同于 value === undefined || value === null
return true;
}
type = Object.prototype.toString.call(value).slice(8, -1);
switch(type) {
case 'String':
return !$.trim(value);
case 'Array':
return !value.length;
case 'Object':
return $.isEmptyObject(value); // 普通对象使用 for...in 判断,有 key 即为 false
default:
return false; // 其他对象均视作非空
}
};
|
对于不同 value
值,我做了个测试,看看对于不同值分别取 Object.prototype.toString
、typeof
、isEmpty
的结果。测试结果可以到下面这个地址围观:
http://jsfiddle.net/Justineo/hFKRt/
除了 IE8 及其以下浏览器外,其他浏览器结果基本一致,下面就贴下主要的 2 种结果吧。下图为 Firefox 下的结果,而在 Chrome 下,window
字符串化后的结果是 'object global',和 Firefox 下稍有不同,但在判断空值时问题不大。
IE8 及以下唯一会误判的是 alert
,不过这对于数据验证来说应该也可以接受。