Javascript之旅——第八站:說說instanceof踩了一個坑

  前些天寫js遇到了一個instanceof的坑,咱們的頁面中有一個iframe,我在index頁面中計算獲得了一個array,而後須要傳遞到Flight頁面javascript

這個嵌套的iframe中的一個函數(SearchFlight)中,做爲防護性編程,我須要在SearchFlight函數中進行參數檢測,也就是判斷過來的參數一html

定是Array類型。java

 

一:拋出問題編程

舉個例子,下面有兩個頁面。數組

Index.html頁面函數

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <title></title>
 5 </head>
 6 <body>
 7 
 8     <iframe name="childframe" src="Flight.html"></iframe>
 9 
10     <script type="text/javascript">
11 
12         window.onload = function () {
13             //航班
14             var airplanes = ["MU", "CA", "CZ"];
15 
16             var result = window.frames[0].flight.SearchFlight(airplanes);
17         };
18     </script>
19 </body>
20 </html>

Flight.html頁面spa

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <title></title>
 5 </head>
 6 <body>
 7     <script type="text/javascript">
 8 
 9         var flight = (function () {
10 
11             return {
12                 SearchFlight: function (arr) {
13                     var result = arr instanceof Array;
14                     alert(result);
15                 }
16             };
17         })();
18     </script>
19 </body>
20 </html>

很驚訝的發現instanceof竟然不能判斷出arr是一個數組,其實咱們用肉眼能夠看到,壓根它就是一個數組,可是爲何instanceof卻判斷不出來呢?prototype

咱們知道instancof實際上是一個js語法糖,我就修改爲簡單點的,判斷arr.constructor是否指向Array,因而我把關鍵字改爲以下形式,再來看看看效果。3d

 1         var flight = (function () {
 2 
 3             return {
 4                 SearchFlight: function (arr) {
 5                     //var result = arr instanceof Array;
 6 
 7                     var result = arr.constructor == Array;
 8 
 9                     alert(result);
10                 }
11             };
12         })();

從圖上看,還真有點奇怪,明明都是function Array(),爲啥都不能相等呢?不過事實就擺在眼前,容不得狡辯,只能靜下心來想想,咱們code

知道Array在js是屬於引用類型,既然不相等那就說明他們實際上是兩個引用,對不對,而且Array是掛在window下的一個屬性,window屬性

也就是一個窗口的實例,那就說明Index.html是一個window實例,Flight.html也是一個window實例,爲了驗證下,咱們看看兩個window

是否相等?

看完圖後,答案就很明白了,以C#的思惟考慮一下,既然大的window都不相等,裏面的Array屬性天然就不相等,終於問題是找到了,下面

怎麼解決呢?

 

二:解決問題

1. length判斷

 這個很容易想到,也是最簡單的,咱們知道每一個數組都有length,因此能夠簡簡單單的看length是否存在就能夠了,可是這個也不是萬無一失

的,咱們知道function中有兩個屬性length和prototype,那這就有問題了。這樣我會錯誤的把f認爲是數組。

 

2.使用prototype的call方法來實現

 這個方法有點巧妙,首先咱們要知道,每個function中都會有call方法和prototype屬性,而js在Object.prototype中的tostring函數上作了一個

封裝,就是調用tostring.call後,會返回[object constructorName]的字符串格式,這裏的constructorName就是call參數的函數名,好比咱們把

arr傳進去,就會返回「[object Array]」字符串格式,這個方法也可讓咱們巧妙的判斷是不是Array,可是比較遺憾的是,咱們看不到這個call的內

部實現,只能黑盒的記住了。

 

相關文章
相關標籤/搜索