1.typeof操作符

示例:
typeof 37 === 'number';? ?? ? ? ? // 數(shù)值
typeof '' === 'string';? ? ? ? ? ? ? ? ?// 字符串
typeof true === 'boolean';??? ? ? // 布爾值
typeof Symbol() === 'symbol';?? // Symbols
typeof undefined === 'undefined';? ? // Undefined
typeof {a: 1} === 'object';? ?
typeof [1, 2, 4] === 'object';? ? ? ? ? ? // 對(duì)象
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String('abc') === 'object';
typeof function() {} === 'function';?? // 函數(shù)?
從上面的實(shí)例我們可以看出,利用typeof除了array和null判斷為object外,其他的都可以正常判斷。
2.instanceof操作符?
這個(gè)操作符和JavaScript中面向?qū)ο笥悬c(diǎn)關(guān)系,了解這個(gè)就先得了解JavaScript中的面向?qū)ο?。因?yàn)檫@個(gè)操作符是檢測(cè)對(duì)象的原型鏈?zhǔn)欠裰赶驑?gòu)造函數(shù)的prototype對(duì)象的。
var arr = [1,2,3,1];
console.log(arr instanceof Array); // true
var fun = function(){};
fun.constructor === Function? // true
第2種和第3種方法貌似無(wú)懈可擊,但是實(shí)際上還是有些漏洞的,當(dāng)你在多個(gè)frame中來(lái)回穿梭的時(shí)候,這兩種方法就亞歷山大了。由于每個(gè)iframe都有一套自己的執(zhí)行環(huán)境,跨frame實(shí)例化的對(duì)象彼此是不共享原型鏈的,因此導(dǎo)致上述檢測(cè)代碼失效
var iframe = document.createElement('iframe'); //創(chuàng)建iframe
document.body.appendChild(iframe); //添加到body中
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // 聲明數(shù)組[1,2,3]
console.log(arr instanceof Array); // false
console.log( arr.constructor === Array )?? ?// false?
4.使用 Object.prototype.toString 來(lái)判斷是否是數(shù)組
Object.prototype.toString.call( [] ) === '[object Array]'? ? //? true
Object.prototype.toString.call( function(){} ) === '[object Function]'? // true
這里使用call來(lái)使 toString 中 this 指向 obj。進(jìn)而完成判斷
5.使用 原型鏈 來(lái)完成判斷
[].__proto__ === Array.prototype? // true
var fun = function(){}
fun.__proto__ === Function.prototype? // true
6.Array.isArray()
Array.isArray([])? // true
ECMAScript5將Array.isArray()正式引入JavaScript,目的就是準(zhǔn)確地檢測(cè)一個(gè)值是否為數(shù)組。IE9+、 Firefox 4+、Safari 5+、Opera 10.5+和Chrome都實(shí)現(xiàn)了這個(gè)方法。但是在IE8之前的版本是不支持的。
總結(jié):
綜上所述,我們可以綜合上面的幾種方法,有一個(gè)當(dāng)前的判斷數(shù)組的最佳寫法:
var arr = [1,2,3];
var arr2 = [{ name : 'jack', age : 22 }];
function isArrayFn(value){
? ?? // 首先判斷瀏覽器是否支持Array.isArray這個(gè)方法
? ?? ?if (typeof Array.isArray === "function") {
? ??????????return Array.isArray(value);
? ??? }else{
? ??????? ? return Object.prototype.toString.call(value) === "[object Array]";
? ? ? ? ? ? // return obj.__proto__ === Array.prototype;
? ? ? }
}
console.log(isArrayFn(arr));? // true
console.log(isArrayFn(arr2));? // true? ?
上述代碼中,為何我們不直接使用原型鏈的方式判斷(兼容性好),而是先判斷瀏覽器支不支持Array.isArray()這個(gè)方法,如果不支持才使用原型鏈的方式呢?我們可以從代碼執(zhí)行效率上看:

?從這張圖片我們可以看到,Array.isArray()這個(gè)方法的執(zhí)行速度比原型鏈的方式快了近一倍。