【发布时间】:2010-01-17 14:01:48
【问题描述】:
有没有办法让一个对象在 javascript 中返回 false?
var obj = new Object();
console.log(!!obj) // prints "true" even if it's empty
【问题讨论】:
标签: javascript
有没有办法让一个对象在 javascript 中返回 false?
var obj = new Object();
console.log(!!obj) // prints "true" even if it's empty
【问题讨论】:
标签: javascript
没有。没有分配任何属性的对象不被视为“空”。
当一个表达式需要一个布尔值时,一个变量包含一个对象的实例这一事实足以导致 javascript 将该变量视为具有true 的值。
编辑
看看这里的其他答案,显然有一些细微差别需要澄清。
null 不是 an 对象,它是对象的明显缺失。问题是指一个对象,即刚刚创建的对象。
【讨论】:
new Boolean(false) 也被视为true。所以不,所有对象都是真实的。
document.all ... 对象 !!document.all 是 false。 (您可以通过Object.keys(document.all).length 或""+document.all 或document.all instanceof Object 来验证document.all 是否存在。)
从 ES8 开始,不,你不能让一个对象在 JavaScript 中计算为 false。
在规范中,所有布尔检查(?!if 等)都依赖于ToBoolean,
这非常非常简单:
如果输入的类型是对象,则结果为真。没有问任何问题。没有valueOf,没有特殊情况。
没有办法在 JavaScript 中创建一个 falsy 对象。 只有非对象可以是虚假的。
有时您可能会遇到返回 false 的类似对象的“东西”。
例如,空字符串一直用于like 一个对象。 document.all 是另一个虚假的“对象”。
然而,这些不是真实的对象。 它们不能有自定义属性,不能用作原型,并且并不总是表现得像一个对象,例如typeof 或严格相等。
这种行为很可能会保留下来以实现向后兼容性。
【讨论】:
document.all 的事情很有趣。虽然,它似乎确实是一个真实的对象。您可以向它添加自定义属性,它可以用作原型,并且它表现就像一个严格相等的对象。它仅在与typeof、松散相等或ToBoolean 一起使用时伪装成undefined。除非您在需要一个虚假对象时牺牲一个新的document.implementation.createHTMLDocument().all,否则这可能根本没有帮助。
Object.create( document.all ) 返回undefined,而在其他浏览器中您丢失了 falsy 属性。在 Firefox 52 中,您不能分配 +ve 数字属性。简而言之,es 或 dom 规范不支持将本机对象用作 falsy 对象,并且您可能会冒着未来的浏览器以难以调试和修复的方式破坏您的代码的风险。
Object.create(document.all) 的结果,但在我的测试中仍然是Object.create(document.all).__proto__ === document.all。关于不可写属性,当然,它们背后有很多魔法,每个浏览器在这方面的行为似乎都不同。
navigator,你会得到损坏的对象,在使用时会抛出奇怪的错误。
空“对象”(真正的值)将返回 false。
var obj = null;
console.log(!!obj);
如果你想检查它是否没有属性,你可以试试:
var obj = new Object();
var empty = true;
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
empty = false;
break;
}
}
console.log(empty);
【讨论】:
没有。但null 将转换为false。
> typeof(null)
"object"
> null instanceof Object
false
> !!null
false
要查看对象是否包含任何属性,请使用(无耻地从How do I count a JavaScript object's attributes? 复制):
function isEmpty (obj) {
for (var k in obj)
if (obj.hasOwnProperty(k))
return false;
return true;
}
【讨论】:
null 是“Null”类型的原始值,而不是对象;只是typeof有点破
typeof 是 JS 关键字而不是函数。括号是不需要的。
没有。
不知道你为什么想要这个,但有一种方法可以让你像这样做,但它有点老套......
var obj = {
toString: function() { return ''; }
};
alert(!! (''+obj));
【讨论】:
false 的情况下,它还附加了值为 false 的原因。如果您可以使布尔运算看起来是错误的,但还附加了一些额外的数据,那么现有代码就不需要更改。不幸的是,这似乎是不可能的。
我认为使用第一个 ! 您将 obj 转换为布尔值并否定它的值 - 如果 obj 为 null - 则导致 true ,而第二个 ! 再次否定它。
【讨论】:
! 将对象转换为布尔值然后否定它。第二个! 否定它再次 使最终结果等同于将对象转换为布尔值。提问者在该陈述中没有问题。
我们可以覆盖Object.prototype.valueOf 以使对象在被强制 转换为原语时显示为假,例如在== 期间。
但是,当我们使用!! 将其强制转换为布尔值时,它不会看起来是假的,所以它在一般情况下并不真正起作用。
var obj = {
valueOf: function () {
return false
}
}
> obj == false
true // Good, we fooled them!
> !!obj
true // Not so good, we wanted false here
> Boolean(obj)
true // Not so good, we wanted false here
【讨论】:
Object-to-boolean 转换是微不足道的。所有对象(包括数组和函数)
转换为真。即使对于 包装对象 (new Boolean(false)) 也是一个对象
而不是原始值,因此它转换为 true。
【讨论】:
你的情况
console.log(!obj); 将返回 false。
因为一个对象或一个空对象总是真实的。
【讨论】: