好程序员Java教程分享JavaScript常见面试题一程序员
好程序员Java教程分享JavaScript常见面试题一:1.使用 typeof bar === "object" 来肯定 bar 是不是对象的潜在陷阱是什么?如何避免这个陷阱?面试
尽管 typeof bar === "object" 是检查 bar 是否对象的可靠方法,使人惊讶的是在JavaScript中 null 也被认为是对象!数组
所以,令大多数开发人员惊讶的是,下面的代码将输出 true (而不是false) 到控制台:闭包
var bar = null;console.log(typeof bar === "object"); // logs true!ide
只要清楚这一点,同时检查 bar 是否为 null,就能够很容易地避免问题:函数
console.log((bar !== null) && (typeof bar === "object")); // logs falsethis
要答全问题,还有其余两件事情值得注意:spa
首先,上述解决方案将返回 false,当 bar 是一个函数的时候。在大多数状况下,这是指望行为,但当你也想对函数返回 true 的话,你能够修改上面的解决方案为:插件
console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));code
第二,上述解决方案将返回 true,当 bar 是一个数组(例如,当 var bar = [];)的时候。在大多数状况下,这是指望行为,由于数组是真正的对象,但当你也想对数组返回 false 时,你能够修改上面的解决方案为:
console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]"));
或者,若是你使用jQuery的话:
console.log((bar !== null) && (typeof bar === "object") && (! $.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 在上面的例子中都是undefined。
然而,事实并不是如此。这里的问题是,大多数开发人员将语句 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 关键字),所以仍然在范围内甚至封闭函数以外。
须要注意的是,在严格模式下(即便用 use strict),语句var a = b = 3; 将生成ReferenceError: b is not defined的运行时错误,从而避免任何不然可能会致使的headfakes /bug。 (仍是你为何应该理所固然地在代码中使用 use strict 的最好例子!)
3.下面的代码将输出什么到控制台,为何?
var myObject = {
foo: "bar",};
myObject.func();
上面的代码将输出如下内容到控制台:
outer func: this.foo = bar
outer func: self.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar
在外部函数中, this 和self 二者都指向了 myObject,所以二者均可以正确地引用和访问 foo。
在内部函数中, this 再也不指向 myObject。其结果是,this.foo 没有在内部函数中被定义,相反,指向到本地的变量self 保持在范围内,而且能够访问。 (在ECMA 5以前,在内部函数中的this 将指向全局的 window 对象;反之,由于做为ECMA 5,内部函数中的功能this 是未定义的。)
4.封装JavaScript源文件的所有内容到一个函数块有什么意义及理由?
这是一个愈来愈广泛的作法,被许多流行的JavaScript库(jQuery,Node.js等)采用。这种技术建立了一个围绕文件所有内容的闭包,也许是最重要的是,建立了一个私有的命名空间,从而有助于避免不一样JavaScript模块和库之间潜在的名称冲突。
这种技术的另外一个特色是,容许一个易于引用的(假设更短的)别名用于全局变量。这一般用于,例如,jQuery插件中。jQuery容许你使用jQuery.noConflict(),来禁用 $ 引用到jQuery命名空间。在完成这项工做以后,你的代码仍然可使用$ 利用这种闭包技术,以下所示:
(function($) { /* jQuery plugin code referencing $ */ } )(jQuery);