JavaScript 中的假值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3982663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Falsey values in JavaScript
提问by Mike Rifgin
I had an interesting interview question today that stumped me a little. I was asked about falsey values. So undefined, NaN, null, 0, and an empty string all evaluate to false. What is the reason this is useful to know in JavaScript? The only thing I can think of is instead of having to do this:
我今天有一个有趣的面试问题,这让我有点难受。我被问到假值。所以 undefined、NaN、null、0 和空字符串都被评估为 false。在 JavaScript 中知道这很有用的原因是什么?我唯一能想到的就是不必这样做:
if (mystring === '' || mystring === undefined) { }
I can do this:
我可以做这个:
if (!mystring)
Is this the only useful application?
这是唯一有用的应用程序吗?
采纳答案by Marcel Korpel
One dangerous issue of falsey values you have to be aware of is when checking the presence of a certain property.
您必须注意的错误值的一个危险问题是检查某个属性是否存在。
Suppose you want to test for the availability of a new property; when this property canactually have a value of 0
or ""
, you can't simply check for its availability using
假设您要测试新属性的可用性;当此属性实际上可以具有0
or值时""
,您不能简单地使用以下方法检查其可用性
if (!someObject.someProperty)
/* incorrectly assume that someProperty is unavailable */
In this case, you mustcheck for it being really present or not:
在这种情况下,您必须检查它是否真的存在:
if (typeof someObject.someProperty == "undefined")
/* now it's really not available */
Also be aware that NaN
isn't equal to anything, even not to itself (NaN != NaN
).
还要注意,NaN
它不等于任何东西,甚至不等于它自己 ( NaN != NaN
)。
回答by kybernetikos
There are two separate issues with 'falsey' values in JavaScript.
JavaScript 中的“falsey”值有两个单独的问题。
Firstly there is the official conversion scheme, which is what is returned by Boolean(x). This returns false when x is false or 0 or NaN or null or undefined or "" and true otherwise. This is the same behaviour as the
首先是官方的转换方案,即Boolean(x)返回的内容。当 x 为 false 或 0 或 NaN 或 null 或 undefined 或 "" 时返回 false,否则返回 true。这是相同的行为
if (condition) {/*true path*/} else {/*false path*/}
that is, the false path is executed if Boolean(condition) would have returned false and the true path is executed otherwise. This behaviour is often used to check to see if a property is defined. However, doing that is not safe unless you are certain that the property would be an object or an array if it is defined. The safest way to test if a property is defined is to do
也就是说,如果 Boolean(condition) 会返回 false,则执行 false 路径,否则执行 true 路径。此行为通常用于检查是否定义了属性。但是,这样做并不安全,除非您确定该属性是一个对象或一个数组(如果它被定义了)。测试属性是否已定义的最安全方法是执行
if (property != null) { /*property is defined*/}
which makes sure that the property is not null or undefined. If you only want to make sure the property is not undefined do
这确保该属性不为空或未定义。如果您只想确保该属性不是未定义的,请执行
if (property !== undefined) { /*property is not undefined (but may be null)*/ }
(notice the extra = in !==).
(注意 !== 中的额外 =)。
Secondly, there are all the values that == false. This is everything that can be coerced to 0 (which is what false gets coerced to). This includes all the values that convert to false except NaN (which can't == false by virtue of it never == anything), null and undefined. But it also includes all objects that when converted to a string and then converted to a number are equal to 0. For example, this includes everything that when converted to a string is either the empty string "" or "0" or "-0" or "+0" or "0x00" or "000" or "0e0" or "0.0000"...., for example,
其次,所有的值都是 == 假的。这是可以强制为 0 的所有内容(这就是 false 被强制为 0 的内容)。这包括所有转换为 false 的值,除了 NaN(它不能 == false 因为它从不 == 任何东西)、null 和 undefined。但它还包括所有在转换为字符串然后转换为数字时等于 0 的对象。例如,这包括转换为字符串时为空字符串 "" 或 "0" 或 "-0" 的所有对象" 或 "+0" 或 "0x00" 或 "000" 或 "0e0" 或 "0.0000"....,例如,
({toString: function() {return "-00.0e000";}}) == false
is true. Interestingly, this includes the empty array, and any nesting of arrays containing only a single other item that returns an empty or 0 string since arrays rendered as strings show only the contents without the surrounding brackets. That is,
是真的。有趣的是,这包括空数组,以及仅包含一个返回空或 0 字符串的其他项的数组的任何嵌套,因为呈现为字符串的数组仅显示没有周围括号的内容。那是,
[[[[0]]]] == false; // Because [[[[0]]]].toString() === "0"
[] == false;
[[[""]]] == false;
["0"] == false;
[[({toString: function() {return "0";}})]] == false;
The full algorithm for calculating == false is described here.
这里描述了计算 == false 的完整算法。
The reason this matters is because it can lead to subtle, difficult to find bugs if you don't understand most of these rules. Most important takeaways are probably how the if (condition)
works and that using === avoids most of the other crazy stuff.
这很重要的原因是因为如果您不了解这些规则中的大部分,它可能会导致微妙的、难以发现的错误。最重要的收获可能是它的if (condition)
工作原理,并且使用 === 避免了大多数其他疯狂的东西。
回答by JAL
It's important to understand how this works in JS, so you're not surprised. Not necessarily just what is falsey, but what is truthy and how they compare to each other.
了解它在 JS 中的工作原理很重要,因此您不会感到惊讶。不一定只是什么是虚假的,而是什么是真实的以及它们如何相互比较。
One example is that '0' is considered equal to 0 with ==, but it is not equal to '' - though 0 is. JavaScript comparison isn't always transitive.
一个例子是 '0' 被认为等于 0 并且 == ,但它不等于 '' - 尽管 0 是。JavaScript 比较并不总是可传递的。
So this means that just because (foo==bar && bar==fizz)
is true, (foo==fizz)
is not always true. To go with the above example, '0'==0, and 0=='', but '0'!='' - because you're comparing strings in the latter instance, so they are compared as strings and not coerced to numbers.
所以这意味着仅仅因为(foo==bar && bar==fizz)
是真的,(foo==fizz)
并不总是真的。按照上面的例子,'0'==0,和 0=='',但是 '0'!='' - 因为你在后一个实例中比较字符串,所以它们作为字符串进行比较而不是强制的到数字。
回答by Harmen
It's useful to detect if a browser is has specific predefined objects:
检测浏览器是否具有特定的预定义对象很有用:
if(!!navigator.geolocation){
// executes if the browser has geolocation support
}
if(!!document.createElement('canvas').getContext){
// executes if the browser supports <canvas>
}
Explanation: navigator.geolocation is an object or undefined. In the case it's an object !navigator.geolocation
will return false, if it's undefined it'll return true. So, to check if a browser has geolocation enabled, you want to 'flip' the boolean once more, by adding another !
.
说明:navigator.geolocation 是一个对象或未定义。如果它是一个对象,!navigator.geolocation
将返回 false,如果它未定义,它将返回 true。因此,要检查浏览器是否启用了地理定位,您需要通过添加另一个!
.
回答by Felix Kling
It is important to know that 0
evaluates to false
to prevent doing things like:
重要的是要知道0
评估false
以防止做以下事情:
if(str.indexOf('foo'))
回答by Mike Ruhlin
They're also useful for setting default values...
它们对于设置默认值也很有用......
function foo(bar){
alert(bar || "default");
}
I know a lot of people try to do
我知道很多人都在尝试做
if (typeof(foo) === "undefined"){}
to get around falsiness, but that's got its own problems because
绕过虚假,但这有其自身的问题,因为
typeof(null) === "object"
for some reason
因为某些原因