一.數(shù)據(jù)類型
JavaScript的數(shù)據(jù)類型可分為兩大類:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型二拐。
1.基本數(shù)據(jù)類型
基本數(shù)據(jù)類型有6種:數(shù)字(Number)、字符串(String)诅病、布爾值(Boolean)哪亿、Undefined粥烁、Null、Symbol(ES6新增)蝇棉。
基礎(chǔ)數(shù)據(jù)類型有以下特點:
- 基本數(shù)據(jù)類型的值是不可變的讨阻,且不可以添加屬性和方法。
- 基本數(shù)據(jù)類型的比較是本身值的比較
- 基本數(shù)據(jù)類型是存儲在棧的
2.引用數(shù)據(jù)類型
引用數(shù)據(jù)類型主要有以下幾種:對象(Object)篡殷、數(shù)組(Array)钝吮、函數(shù)(Function)、還有兩個特殊的對象:正則(RegExp)和日期(Date)板辽。
引用數(shù)據(jù)類型有以下特點:
- 引用數(shù)據(jù)類型的值是可變的奇瘦,且可以添加屬性和方法
- 引用數(shù)據(jù)類型的比較是引用對象的比較
- 引用數(shù)據(jù)類型的值是保存在堆內(nèi)存的一個對象,棧內(nèi)存保存的是指向這個對象的指針(或者說堆內(nèi)存的地址)
二.類型判斷
1.typeof
typeof返回一個表示數(shù)據(jù)類型的字符串劲弦,返回結(jié)果包括:number耳标、string、boolean邑跪、object次坡、undefined、function画畅。typeof可以對基本類型number砸琅、string 、boolean轴踱、undefined做出準(zhǔn)確的判斷(null除外症脂,typeof null===“object”,這是由于歷史遺留bug)淫僻;而對于引用類型诱篷,除了function之外返回的都是object。但當(dāng)我們需要知道某個對象的具體類型時嘁傀,typeof就顯得有些力不從心了
typeof 1; // number 有效
typeof ‘ ’;//string 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof null; //object 無效
typeof new Function(); // function 有效
typeof [] ; //object 無效
typeof new Date(); //object 無效
typeof new RegExp(); //object 無效
2.instanceof
instanceof 是用來判斷 A 是否為 B 的實例兴蒸,表達(dá)式為:A instanceof B,如果 A 是 B 的實例细办,則返回 true,否則返回 false橙凳。 在這里需要特別注意的是:instanceof 檢測的是原型。我們用一段偽代碼來模擬instanceof內(nèi)部執(zhí)行過程:
instanceof (A,B) = {
var L = A.__proto__;
var R = B.prototype;
if(L === R) {
//A的內(nèi)部屬性__proto__指向B的原型對象
return true;
}
return false;
}
從上述過程可以看出笑撞,當(dāng) A 的 proto 指向 B 的 prototype 時岛啸,就認(rèn)為A就是B的實例,我們再來看幾個例子:
[] instanceof Array; //true
[] instanceof Object; //true
new Date() instanceof Date;//true
new Date() instanceof Object;//true
function Person(){};
new Person() instanceof Person;//true
new Person() instanceof Object;//true
我們發(fā)現(xiàn)茴肥,雖然 instanceof 能夠判斷出 [] 是Array的實例坚踩,但它認(rèn)為 [] 也是Object的實例,為什么呢瓤狐? 我們來分析一下[]瞬铸、Array批幌、Object 三者之間的關(guān)系: 從instanceof 能夠判斷出 [].proto 指向 Array.prototype, 而 Array.prototype.proto 又指向了Object.prototype嗓节,Object.prototype.proto 指向了null,標(biāo)志著原型鏈的結(jié)束荧缘。因此,[]拦宣、Array截粗、Object就形成了如下圖所示的一條原型鏈:
從原型鏈可以看出,[] 的 proto 直接指向Array.prototype, 間接指向Object.prototype, 所以按照 instanceof 的判斷規(guī)則鸵隧,[] 就是Object的實例绸罗。
3.toString
前面的typeof和instanceof都有一定局限性,最后一個toString是比較萬能的方法豆瘫。
toString() 是 Object 的原型方法珊蟀,調(diào)用該方法,默認(rèn)返回當(dāng)前對象的 [[Class]] 外驱。這是一個內(nèi)部屬性系洛,其格式為 [object Xxx] ,其中 Xxx 就是對象的類型略步。
對于 Object 對象,直接調(diào)用 toString() 就能返回 [object Object] 定页。而對于其他對象趟薄,則需要通過 call / apply 來調(diào)用才能返回正確的類型信息。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object Window]