好程序员 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!
只要清楚这一点,同时检查 bar 是否为 null ,就可以很容易地避免问题:
console.log((bar !== null) && (typeof bar === "object")); // logs false
要答全问题,还有其他两件事情值得注意:
首先,上述解决方案将返回 false ,当 bar 是一个函数的时候。在大多数情况下,这是期望行为,但当你也想对函数返回 true 的话,你可以修改上面的解决方案为:
console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));
第二,上述解决方案将返回 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);
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69913892/viewspace-2661426/ ,如需转载,请注明出处,否则将追究法律责任。