一些很经典的JavaScript探讨题,分享分享,英语好的可以忽略我的翻译。
[译]:一些必要的(基本的)JS面试题及答案
What is a potential pitfall with using typeof bar === "object" to determine if bar is an object? How can this pitfall be avoided ?
[译]:使用typeof bar === "object"判断bar是不是一个对象存在什么潜在的缺陷?如何避免这个缺陷?
Although typeof bar === "object"
is a reliable way of checking if bar
is an object, the surprising gotcha in JavaScript is that null
is also considered an object!
[译]:虽然 typeof bar === "object" 是检查bar是否是对象的可靠方法,但令人惊讶的是在JavaScript中 null 也是被视为对象的!
Therefore, the following code will, to the surprise of most developers, log true
(not false
) to the console:
[译]:因此,以下代码将会使很多开发人员感到惊讶,因为在控制台中输出的是true而不是false。
var bar = null;
console.log(typeof bar === "object"); // logs true!
As long as one is aware of this, the problem can easily be avoided by also checking if bar
is null
:
[译]:只要意识到这点,同时检查bar是否为null的话,就能很容易地避免这个问题:
console.log((bar !== null) && (typeof bar === "object")); // logs false
To be entirely thorough in our answer, there are two other things worth noting:
First, the above solution will return false
if bar
is a function. In most cases, this is the desired behavior, but in situations where you want to also return true
for functions, you could amend the above solution to be:
[译]:要回答得全面的话,还有其他两件事情值得注意:
第一,假如bar是一个函数的时候,上述解决方案将返回false。多数情况下,这是期望的行为,当你也想对函数返回true的话,可以将上述方案修改为:
console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));
Second, the above solution will return true
if bar
is an array (e.g., if var bar = [];
). In most cases, this is the desired behavior, since arrays are indeed objects, but in situations where you want to also false
for arrays, you could amend the above solution to be:
[译]:第二,当bar是一个数组的时候,上述方案将返回true。多数情况下,这个预期的行为,因为数组实际上也是对象,当你想对数组返回false时,你可以将上述方案修改为:
console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]"));
However, there’s one other alternative that returns false
for nulls, arrays, and functions, but true
for objects:
[译]:然而,这里有一种可替代的方案,当bar是null、数组、函数时会返回false,当bar时object时返回true。
console.log((bar !== null) && (bar.constructor === Object));
Or, if you’re using jQuery:
[译]:如果你使用JQuery的话,还可以这样:
console.log((bar !== null) && (typeof bar === "object") && (! $.isArray(bar)));
ES5 makes the array case quite simple, including its own null check:
[译]:ES5使得数组的情况很简单,包括它自身的null校验:
console.log(Array.isArray(bar));
What will the code below output to the console and why?
[译]:以下代码在console中的输出结果是?为什么?
(function(){
var a = b = 3;
})();
console.log("a defined? " + (typeof a !== 'undefined'));
console.log("b defined? " + (typeof b !== 'undefined'));
Since both a
and b
are defined within the enclosing scope of the function, and since the line they are on begins with the var
keyword, most JavaScript developers would expect typeof a
and typeof b
to both be undefined in the above example. However, that is not the case. The issue here is that most developers incorrectly understand the statement var a = b = 3;
to be shorthand for:
[译]:由于 a 和 b 都定义在函数的封闭范围内,并且都始于 var关键字,大多数JavaScript开发人员期望 typeof a 和 typeof b 在上面的例子中都是undefined。然而,事实并非如此。这里的问题是,大多数开发人员将语句 var a = b = 3; 错误地理解为是以下声明的简写:
var b = 3;
var a = b;
But in fact, var a = b = 3;
is actually shorthand for:
[译]:但事实上,var a = b = 3是以下写法的简写:
b = 3;
var a = b;
As a result (if you are not using strict mode), the output of the code snippet would be:
[译]:因此(如果你没有使用严格模式的话),该代码段的输出是:
a defined? false
b defined? true
But how can b
be defined outside of the scope of the enclosing function? Well, since the statement var a = b = 3;
is shorthand for the statements b = 3;
and var a = b;
, b
ends up being a global variable (since it is not preceded by the var
keyword) and is therefore still in scope even outside of the enclosing function.
[译]:但是, b
是怎样被定义在封闭函数的范围之外的呢?是的,既然语句 var a = b = 3;
是语句 b = 3;
和 var a = b;
的简写, b
最终成为了一个全局变量(因为它没有前缀 var
关键字),因此仍然在范围内甚至封闭函数之外。(本人提醒:即例子中的b可以通过windows.b访问到)
Note that, in strict mode (i.e., with use strict
), the statement var a = b = 3;
will generate a runtime error of ReferenceError: b is not defined
, thereby avoiding any headfakes/bugs that might othewise result. (Yet another prime example of why you should use use strict
as a matter of course in your code!)
use strict
),语句var a = b = 3;
将生成运行时错误:ReferenceError: b is not defined
,从而避免可能会导致的麻烦或者八阿哥。 (还是你为什么应该理所当然地在代码中使用 use strict
的最好例子!)