1、使用typeof bar ===“object”来确定bar是否是一个对象时有什么潜在的缺陷?这个陷阱如何避免?
尽管typeof bar ===“object”是检查bar是否是对象的可靠方法,但JavaScript中令人惊讶的问题是null也被认为是一个对象!
因此,下面的代码打印到控制台的是true而不是false:
var bar = null;
console.log(typeof bar === "object"); // logs true!
只要知道这一点,就可以通过检查bar是否为空来轻松避免该问题:
console.log((bar !== null) && (typeof bar === "object")); // logs false
为了在我们的答案更加的完整,还有两件事值得注意:
首先,如果bar是一个函数,上面的解决方案将返回false。在大多数情况下,这是所期望的行为,但是在您希望函数返回true的情况下,您可以将上述解决方案修改为:
console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));
其次,如果bar是数组,则上述解决方案将返回true(例如,如果var bar = [];)。在大多数情况下,这是所希望的行为,因为数组确实是对象,但是在您想要对数组也是false的情况下,可以将上述解决方案修改为:
console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]"));
但是,还有一个替代方法对空值,数组和函数返回false,但对于对象则为true:
console.log((bar !== null) && (bar.constructor === Object));
或者,如果您使用jQuery:
console.log((bar !== null) && (typeof bar === "object") && (! $.isArray(bar)));
ES5使得数组的情况非常简单,包括它自己的空检查:
console.log(Array.isArray(bar));
2、下面的代码将输出到控制台的是什么,为什么?
(function(){ var a = b = 3;})();console.log("a defined? " + (typeof a !== 'undefined'));console.log("b defined? " + (typeof b !== 'undefined'));
由于a和b都在函数的封闭范围内定义,并且由于它们所在的行以var关键字开头,因此大多数JavaScript开发人员会希望typeof a和typeof b在上面的示例中都未定义。
但是,情况并非如此。这里的问题是大多数开发人员错误地理解语句var a = b = 3;以下简写为:
var b = 3;var a = b;
但实际上,var a = b = 3;其实是速记:
b = 3;
var a = b;
因此(如果您不使用严格模式),代码片段的输出将为:
a defined? falseb defined? true
但是如何在封闭函数的范围之外定义b?那么,因为声明var a = b = 3;是语句b = 3的简写;并且var a = b; b最终成为一个全局变量(因为它不在var关键字后面),因此它仍然在作用域内,即使在封闭函数之外。
注意,在严格模式下(即,使用strict),语句var a = b = 3;会产生一个ReferenceError的运行时错误:b没有定义,从而避免了可能导致的任何头headfakes/bugs。 (这就是为什么你应该在你的代码中使用strict,一个重要的例子!)
3、下面的代码将输出到控制台的是什么?,为什么?
var myObject = {
foo: "bar