Javascript:一个空对象是否为假值?

77
空对象是未定义的,例如var empty_obj = {}
未定义的对象会被视为false。但我注意到empty_obj || 3将返回empty_obj而不是3
为什么会这样?

2
为什么它应该是假的?所有对象都是真实的,事实上许多其他语言也会这样做,这是完全合理的。 - hugomg
17
尝试使用if (Object.keys(obj).length)来检查是否为空。 - elclanrs
2
如何在JavaScript中检查对象是否为空? - AndyDaSilva52
如果(!obj)就太好了... - RaisinBranCrunch
4个回答

112

空对象并不是undefined。

console.log({} === undefined); // false
console.log(typeof {}); // object

这是一个真值:

if ({}) console.log('truthy'); // truthy

它甚至具有一些属性:

console.log(typeof {}.hasOwnProperty); // function
在JS中,唯一的假值包括0falsenullundefined、空字符串和NaN
您可能会对var =语句的返回值感到困惑。在Chrome控制台中,这些语句的返回值始终显示为undefined
> var obj = {}
undefined
> var x = 100
undefined
> var y = "potato"
undefined

仅仅因为var =语句返回undefined并不意味着值是undefined。但是,如果没有使用var,赋值确实会返回被赋的值:

> obj = {}
{}
> x = 100
100
> y = "potato"
"potato"

8
为什么 {} == true 返回 false? - Kevin Bowersox
16
@KevinBowersox 的表达 "truthy" !== == true 意思是 "truthy" 不等于 == true。同时,{} == false 的返回值也为 false。而 "some string" == true 的返回值同样是 false。 - tckmn
3
注意,你可以通过添加额外的感叹号来模拟一个布尔比较运算符;alert(!!{} == !!true)可以查看两个变量是否布尔比较相同。由于你是对两者进行操作,所以可以缩短为alert(!{} == !true),并得到与双重感叹号相同的结果。你也可以使用+前缀将其作为数字进行比较;alert(+"4"==+4),以及""+将其作为字符串进行比较;alert(""+5==""+"5")。 - dandavis
1
请注意,document.all 也是假值。 - trincot
对于编程人员来说,“truthy”意味着Python中的“真值”。 - Kishore

9

如上面的答案所述,在JavaScript中,空对象并不是假值。

那么如何正确地检查一个对象是否为空呢?

Object.keys(obj).length === 0 && obj.constructor === Object

为什么需要额外的构造函数检查?

你可能会问为什么需要构造函数检查。这是为了覆盖包装实例。在JavaScript中,我们有9个内置构造函数。

new String();
new Number();
new Boolean();
new Array();
new RegExp();
new Function();
new Date();

我们可以使用new Object()创建一个空对象。顺便说一下:永远不要使用构造函数来创建对象,这被认为是不良实践。

const obj = new Object();

Object.keys(obj).length === 0; // true

仅使用 Object.keys,当对象为空时返回true。但是,当我们使用其他构造函数创建新的对象实例时,它不起作用

Object.keys(new String()).length === 0 // false

因此,对于对象实例,构造函数检查是必要的。

function isEmptyObj(obj) {
    return Object.keys(obj).length === 0 && obj.constructor === Object;
}

console.log(isEmptyObj({}));

P.S

这段代码仅适用于对象,不适用于未定义或空值。


刚刚检查了一下:Object.keys(new String()).length === 0 // true 问题出在Date()对象上: - DaveX

3
空对象并不是未定义的,只有类型为 undefined1 的对象才是未定义的:
[timwolla@~]node
> undefined == {}
false
> typeof {}
'object'
> typeof undefined
'undefined'

1 在非严格模式下,可以重新定义 undefined。使用 typeof 或比较 void 0 更为安全。


谢谢@TimWolla,我明白你的观点。当我在Chrome控制台中测试时,输入var obj={}后,Chrome会回复undefined。 - Bargitta
2
@Bargitta 当你输入var x = 100后,它会返回undefined。var =赋值语句总是返回undefined。 - tckmn

2

您定义了empty_obj作为一个对象,它恰好没有定义任何属性,但是它被定义了。因此,empty_obj的结果是真值,并在赋值时返回。

var myobj = {}; //defined
var myobj2;     //undefined

if(myobj == undefined)
{
    console.log("myobj is undefined");
}
if(myobj2 == undefined)
{
    console.log("the 2nd one is undefined");
}
if(myobj)
{
    console.log("myobj isn't falsy");
}
if(myobj2)
{
     console.log("myobj2 isn't false");
}

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