js中只有六種
原始數據類型和一個Object
:jquery
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (ECMAScript 6 新定義)
- Object
你們認真記清這個描述,不要到時候把Array、Date都當成js的數據類型就尷尬了。那可能會有人問,那Array和Date算什麼呢,他們都屬於Object,看下面分類:數組
Object分爲 本地對象、 內置對象和 宿主對象三種
定義:獨立於宿主環境的ECMAScript實現提供的對象。簡單的說就是ECMA定義的類。他們包括:
Object Function Array String Boolean Number Date RegExp Error EvalError RangeError ReferenceError SyntaxError TypeError URIError
因此Array和Date都屬於對象類型,它們是本地對象。瀏覽器
1.有人可能會問,爲何String也是Object類型,上面不是說了是原始類型嗎?
答:原始類型中有字符串String不錯,它只是表達了一種數據類型,但數據類型也有本身的類定義啊,是吧,上面的String說的就是它的類型定義,是個對象,因此固然也是引用類型了。其餘同理。
看下面demo函數
var str1='hello'; var str2=new String("hello"); typeof str1 //string typeof str2 //object //若是想獲取str2的字符串,能夠經過str2.toString() str1 instanceof String //false str2 instanceof String //true
定義:「由ECMAScript實現提供的、獨立於宿主環境的全部對象,在ECMAScript程序開始執行時出現」。這意味着開發者沒必要明確實例化內置對象,它已經被實例化了。
內置對象只有兩個Global
和Math
,他們其實也是本地對象,根據定義每一個內置對象都是本地對象。
全部非本地對象都是宿主對象,即由ECMAScript實現的宿主環境提供的對象。全部BOM
和DOM
對象都是宿主對象。
最多見的判斷方法:typeof,它的官方解釋:測試
typeof操做符返回一個字符串,表示未經計算的操做數的類型。
簡單理解就是typeof
是判斷的是原始類型(值類型),但函數返回的是function
,null返回的也是object
typeof Undefined //'undefined' var num; typeof num //undefined
類型 | 結果 |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Symbol (ECMAScript 6 新增) | "symbol" |
宿主對象(由JS環境提供) | Implementation-dependent |
函數對象([[Call]] 在ECMA-262條款中實現了) | "function" |
任何其餘對象 | "object" |
在 JavaScript 最初的實現中,JavaScript 中的值是由一個表示類型的標籤和實際數據值表示的。對象的類型標籤是 0。因爲 null 表明的是空指針(大多數平臺下值爲 0x00),所以,null的類型標籤也成爲了 0,typeof null就錯誤的返回了"object"。
優勢 | 缺點 |
---|---|
判斷原始類型比較方便 | null返回的是object |
方法返回的是function | |
全部的引用類型都返回object,Array、Date等不能準肯定位 |
定義:「instanceof 運算符用來測試一個 對象(第一個參數)在其原型鏈中是否存在一個構造函數(第二個參數)的 prototype 屬性。」
簡單理解就是:instanceof是判斷兩個對象「最近」prototype是否同樣。
另外,instanceof是判斷對象是否屬於某一類型,而不是獲取的對象的類型。
var str1="hello"; var str2=new String("hello"); var arr=[1,2,3]; function person(){} function man(){} man.prototype=new person(); var m1=new person(); var m2=new man(); str1 instanceof String //false str2 instanceof String //true arr instanceof Array //true arr instanceof window.frames[0].Array //false m1 instanceof person //true m2 instanceof man //true m2 intanceof person //true
優勢 | 缺點 |
---|---|
判斷對象的具體類型 | 只能判斷對象,對原始類型不能判斷 |
多全局對象時返回不正確 |
簡單來講:多全局對象就是跨窗口或跨frame操做。
在瀏覽器中,咱們的腳本可能須要在多個窗口之間進行交互。多個窗口意味着多個全局環境,不一樣的全局環境擁有不一樣的全局對象,從而擁有不一樣的內置類型構造函數。
這可能會引起一些問題。
好比,表達式 [] instanceof window.frames[0].Array 會返回false,由於 Array.prototype !== window.frames[0].Array.prototype,所以你必須使用 Array.isArray(myObj) 或者 Object.prototype.toString.call(myObj) === "[object Array]"來判斷myObj是不是數組。prototype
alert(c.constructor === Array) ----------> true alert(d.constructor === Date) -----------> true alert(e.constructor === Function) -------> true 注意: constructor 在類繼承時會出錯 eg: function A(){}; function B(){}; A.prototype = new B(); //A繼承自B var aObj = new A(); alert(aobj.constructor === B) -----------> true; alert(aobj.constructor === A) -----------> false; 而instanceof方法不會出現該問題,對象直接繼承和間接繼承的都會報true: alert(aobj instanceof B) ----------------> true; alert(aobj instanceof B) ----------------> true; 言歸正傳,解決construtor的問題一般是讓對象的constructor手動指向本身: aobj.constructor = A; //將本身的類賦值給對象的constructor屬性 alert(aobj.constructor === A) -----------> true; alert(aobj.constructor === B) -----------> false; //基類不會報true了;
缺點:繼承的對象判斷時,不許確。感受雞肋。指針
最靠譜的方法: Object.prototype.toString.call(obj)code
Object
,因此自定義時仍是使用instanceof
。var str1="hello"; var str2=new String("hello"); var arr=[1,2,3]; function Man(){} var man=new Man(); Object.prototype.toString.call(str1); //[object String] Object.prototype.toString.call(str2); //[object String] Object.prototype.toString.call(arr); //[object Array] Object.prototype.toString.call(man); //[object Object] Object.prototype.toString.call(null); //[object Null] Object.prototype.toString.call(/test/) //[object RegExp]
優勢 | 缺點 |
---|---|
不存在多全局環境問題 | 只能判斷本地對象和宿主對象 |
原始類型不管是字面量語法聲明仍是經過對應的引用類型聲明都能正確判斷 | 自定義類型都返回[object Object] |
就是對prototype的封裝。源碼附上:對象
type: function( obj ) { return obj == null ? String( obj ) : class2type[ toString.call(obj) ] || "object"; },
var arr=[1,2,3]; typeof arr //object 分辨不出類型 arr instanceof Array //true //受多全局環境影響 Object.prototype.toString.call(arr); //[object Array] //推薦 Array.isArray(arr) //true //推薦 $.type(arr) //array //推薦