好程序员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!

  只要清楚这一点,同时检查 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 和 都定义在函数的封闭范围内,并且都始于 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;的简写, 最终成为了一个全局变量(因为它没有前缀 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(jQueryNode.js)采用。这种技术创建了一个围绕文件全部内容的闭包,也许是最重要的是,创建了一个私有的命名空间,从而有助于避免不同JavaScript模块和库之间潜在的名称冲突。

  这种技术的另一个特点是,允许一个易于引用的(假设更短的)别名用于全局变量。这通常用于,例如,jQuery插件中。jQuery允许你使用jQuery.noConflict(),来禁用 引用到jQuery命名空间。在完成这项工作之后,你的代码仍然可以使用利用这种闭包技术,如下所示:

  (function($) { /* jQuery plugin code referencing $ */ } )(jQuery);