今天我遇到了一个有趣的面试问题,这让我有点难受。我被问到假值。所以 undefined、NaN、null、0 和空字符串都被评估为 false。在 JavaScript 中知道这很有用的原因是什么?我唯一能想到的就是不必这样做:
if (mystring === '' || mystring === undefined) { }
我可以做这个:
if (!mystring)
这是唯一有用的应用程序吗?
今天我遇到了一个有趣的面试问题,这让我有点难受。我被问到假值。所以 undefined、NaN、null、0 和空字符串都被评估为 false。在 JavaScript 中知道这很有用的原因是什么?我唯一能想到的就是不必这样做:
if (mystring === '' || mystring === undefined) { }
我可以做这个:
if (!mystring)
这是唯一有用的应用程序吗?
您必须注意的错误值的一个危险问题是检查某个属性是否存在。
假设您要测试新房产的可用性;当此属性实际上可以具有0
or值时""
,您不能简单地使用以下方法检查其可用性
if (!someObject.someProperty)
/* incorrectly assume that someProperty is unavailable */
在这种情况下,您必须检查它是否真的存在:
if (typeof someObject.someProperty == "undefined")
/* now it's really not available */
还要注意,NaN
它不等于任何东西,甚至不等于它自己 ( NaN != NaN
)。
JavaScript 中的“falsey”值有两个不同的问题。
首先是官方的转换方案,即Boolean(x)返回的内容。当 x 为假或 0 或 NaN 或 null 或未定义或 "" 时返回假,否则返回真。这是相同的行为
if (condition) {/*true path*/} else {/*false path*/}
也就是说,如果 Boolean(condition) 会返回 false,则执行 false 路径,否则执行 true 路径。此行为通常用于检查是否定义了属性。但是,这样做并不安全,除非您确定该属性是一个对象或一个数组(如果已定义)。测试属性是否已定义的最安全方法是执行
if (property != null) { /*property is defined*/}
这确保该属性不为空或未定义。如果您只想确保该属性不是未定义的,请执行
if (property !== undefined) { /*property is not undefined (but may be null)*/ }
(注意 !== 中的额外 =)。
其次,所有的值都是 == 假的。这是可以强制为 0 的所有内容(这就是 false 被强制为 0 的内容)。这包括所有转换为 false 的值,除了 NaN(它不能 == false,因为它从不 == 任何东西)、null 和 undefined。但它还包括所有在转换为字符串然后转换为数字时等于 0 的对象。例如,这包括转换为字符串时为空字符串 "" 或 "0" 或 "-0" 的所有对象" 或 "+0" 或 "0x00" 或 "000" 或 "0e0" 或 "0.0000"....,例如,
({toString: function() {return "-00.0e000";}}) == false
是真的。有趣的是,这包括空数组,以及仅包含一个返回空或 0 字符串的其他项的数组的任何嵌套,因为呈现为字符串的数组仅显示没有周围括号的内容。那是,
[[[[0]]]] == false; // Because [[[[0]]]].toString() === "0"
[] == false;
[[[""]]] == false;
["0"] == false;
[[({toString: function() {return "0";}})]] == false;
这里描述了计算 == false 的完整算法。
这很重要的原因是因为如果您不了解这些规则中的大部分,它可能会导致微妙的、难以发现的错误。最重要的收获可能是它的if (condition)
工作原理,并且使用 === 避免了大多数其他疯狂的东西。
了解它在 JS 中的工作原理很重要,因此您不会感到惊讶。不一定只是什么是虚假的,而是什么是真实的以及它们如何相互比较。
一个例子是,'0' 被认为等于 0 和 ==,但它不等于 '' - 尽管 0 是。JavaScript 比较并不总是可传递的。
所以这意味着仅仅因为(foo==bar && bar==fizz)
是真的,(foo==fizz)
并不总是真的。按照上面的例子,'0'==0,和 0=='',但是 '0'!='' - 因为你在后一个实例中比较字符串,所以它们作为字符串进行比较而不是强制的到数字。
重要的是要知道0
评估false
以防止做以下事情:
if(str.indexOf('foo'))
检测浏览器是否具有特定的预定义对象很有用:
if(!!navigator.geolocation){
// executes if the browser has geolocation support
}
if(!!document.createElement('canvas').getContext){
// executes if the browser supports <canvas>
}
说明:navigator.geolocation 是一个对象或未定义。如果它是一个对象,!navigator.geolocation
将返回 false,如果它未定义,它将返回 true。因此,要检查浏览器是否启用了地理定位,您需要通过添加另一个!
.