Javascript裡instanceo的坑
前些天寫js遇到了一個instanceof的坑,我們的頁面中有一個iframe,我在index頁面中計算得到了一個array,然後需要傳遞到Flight頁面
這個巢狀的iframe中的一個函式(SearchFlight)中,作為防禦性程式設計,我需要在SearchFlight函式中進行引數檢測,也就是判斷過來的引數一
定是Array型別。
一:丟擲問題
舉個例子,下面有兩個頁面。
1 html> 2 3 45 6 7 8 9 10
1 html> 2 3 45 6 7
很驚訝的發現instanceof居然不能判斷出arr是一個陣列,其實我們用肉眼可以看到,壓根它就是一個陣列,但是為什麼instanceof卻判斷不出來呢?
我們知道instancof其實是一個js語法糖,我就修改成簡單點的,判斷arr.constructor是否指向Array,於是我把關鍵字改成如下形式,再來看看看效果。
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(),為啥都不能相等呢?不過事實就擺在眼前,容不得狡辯,只能靜下心來想一想,我們
知道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的內
部實現,只能黑盒的記住了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4550/viewspace-2801316/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python裡的那些坑Python
- Laravel裡的那些坑 - OptionalLaravel
- JavaScript裡的函式JavaScript函式
- JavaScript 裡的 Promise ChainingJavaScriptPromiseAI
- JavaScript正則爬坑JavaScript
- javascript對深拷貝物件的研坑JavaScript物件
- JavaScript深拷貝的一些坑JavaScript
- JavaScript設計模式入坑JavaScript設計模式
- JavaScript 裡三個點 ... 的用法JavaScript
- javascript ==與!=的比較規則(加踩坑)JavaScript
- JavaScript陣列裡的slice和spliceJavaScript陣列
- JavaScript 中 this 的執行機制及爬坑指南JavaScript
- JavaScript中this的執行機制及爬坑指南JavaScript
- nodejs request module裡的json引數的一個坑NodeJSJSON
- ABAP,Java,JavaScript裡的字串模板String TemplateJavaScript字串
- 沒想到Swift裡KVC還能有坑Swift
- JavaScript 倒數計時踩坑集錦JavaScript
- JavaScript作用域面試題避坑指南JavaScript面試題
- 聊一聊JavaScript中的嚴格模式與相關的‘坑’JavaScript模式
- 曾經面試踩過的坑,都在這裡了~面試
- 別再被坑了! JavaScript型別檢測的最佳實踐JavaScript型別
- JavaScript 在 Promise.then 方法裡返回新的 PromiseJavaScriptPromise
- ElasticSearch裡面一些小坑筆記Elasticsearch筆記
- JavaScript,你從哪裡來?(上)JavaScript
- JavaScript,你從哪裡來?(下)JavaScript
- JavaScript取出字串中括號裡的內容JavaScript字串
- JavaScript, ABAP和Scala裡的尾遞迴(Tail Recursion)JavaScript遞迴AI
- 一個@Transaction哪裡來這麼多坑?
- 帶你全面瞭解 Flutter,它好在哪裡?它的坑在哪裡? 應該怎麼學?Flutter
- [譯]JavaScript async / await:好處、坑和正確用法JavaScriptAI
- 前端之路---入坑篇之JavaScript基礎筆記前端JavaScript筆記
- javascript程式碼放在什麼裡面JavaScript
- 在2018年裡關於測試JavaScript的回顧JavaScript
- 聽說你還不理解JavaScript裡的閉包JavaScript
- 你真的會用ABAP, Java和JavaScript裡的constructor麼?JavaScriptStruct
- 那些年你踩過的坑,都在這裡了~| 掘金技術徵文
- JavaScript 非同步操作裡的巢狀回撥函式JavaScript非同步巢狀函式
- windows server 2012 R2裡IIS配置.net core2.1遇到的坑WindowsServer