天天看點

JavaScript常見面試題一

  好程式員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 和 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);