JS數據類型分類和判斷

在前端筆試面試中「JS數據類型的分類和判斷」是高頻的基礎考點,今天總結一下,對正在準備找工做的小夥伴應該有所幫助~ 前端

JavaScript中有6種數據類型:數字(number)、字符串(string)、布爾值(boolean)、undefined、null、對象(Object)。其中對象類型包括:數組(Array)、函數(Function)、還有兩個特殊的對象:正則(RegExp)和日期(Date)。面試

1、分類

從不一樣的角度對6種數據類型進行分類: 數組

2、判斷

一、typeof

typeof返回一個表示數據類型的字符串,返回結果包括:number、string、boolean、object、undefined、function。typeof能夠對基本類型number、string  、boolean、undefined作出準確的判斷(null除外,typeof null===「object」,這是因爲歷史的緣由,我就不巴拉巴拉了,其實我也說不清楚😢);而對於引用類型,除了function以外返回的都是object。但當咱們須要知道某個對象的具體類型時,typeof就顯得有些力不從心了。 bash

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 無效
複製代碼

二、instanceof

當咱們須要知道某個對象的具體類型時,能夠用運算符 instanceof,instanceof操做符判斷左操做數對象的原型鏈上是否有右邊這個構造函數的prototype屬性,也就是說指定對象是不是某個構造函數的實例,最後返回布爾值。 檢測的咱們用一段僞代碼來模擬instanceof內部執行過程: 微信

instanceof (A,B) = {
    var L = A.__proto__;
    var R = B.prototype;
    if(L === R) {
        //A的內部屬性__proto__指向B的原型對象
        return true;
    }
    return false;
}
複製代碼

從上述過程能夠看出,當 A 的 __proto__ 指向 B 的 prototype 時,就認爲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

複製代碼

咱們發現,雖然 instanceof 可以判斷出 [] 是Array的實例,但它認爲 [] 也是Object的實例,爲何呢? 咱們來分析一下[]、Array、Object 三者之間的關係: 從instanceof 可以判斷出 [].__proto__ 指向 Array.prototype, 而 Array.prototype.__proto__ 又指向了Object.prototype,Object.prototype.__proto__ 指向了null,標誌着原型鏈的結束。所以,[]、Array、Object就造成了以下圖所示的一條原型鏈: ui

從原型鏈能夠看出,[] 的 __proto__  直接指向Array.prototype, 間接指向Object.prototype, 因此按照 instanceof 的判斷規則,[] 就是Object的實例。this

注意:instanceof運算符只能用於對象,不適用原始類型的值。spa

'hello' instanceof String // false
null instanceof Object // false
undefined instanceof Object // false
複製代碼

字符串、null和undefined不是對象,因此返回false。 prototype

三、constructor

constructor屬性的做用是,能夠得知某個實例對象,究竟是哪個構造函數產生的。

var f = new F();
f.constructor === F;// true
複製代碼

可是 constructor 屬性易變,不可信賴,這個主要體如今自定義對象上,當開發者重寫prototype後,原有的constructor會丟失。

function F() {}
F.prototype = {
	_name: 'Eric',
};
var f = new F();
f.constructor === F; // false

複製代碼

所以,爲了規範,在重寫對象原型時通常都須要從新給constructor賦值,以保證明例對象的類型不被改寫。

function F() {}
F.prototype = {
    constructor: F, 
   _name: 'Eric',
};
var f = new F();
f.constructor === F; // true 
複製代碼

四、Object.prototype.toString 

toString是Object原型對象上的一個方法,該方法默認返回其調用者的具體類型,更嚴格的講,是 toString運行時this指向的對象類型, 返回的類型格式爲[object,xxx],xxx是具體的數據類型,其中包括:String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,... 基本上全部對象的類型均可以經過這個方法獲取到。

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]

複製代碼

須要注意的是,必須經過Object.prototype.toString.call來獲取,而不能直接 new Date().toString(), 從原型鏈的角度講,全部對象的原型鏈最終都指向了Object, 按照JS變量查找規則,其餘對象應該也能夠直接訪問到Object的toString方法,而事實上,大部分的對象都實現了自身的toString方法,這樣就可能會致使Object的toString被終止查找,所以要用call來強制執行Object的toString方法。

3、總結:

typeof能夠準確地判斷出基本類型,可是對於引用類型除function以外返回的都是object;

已知是引用類型的狀況能夠選用instanceof或constructor方法進行具體類型的判斷:

instanceof是基於原型鏈的;

constructor 屬性易變,不可信賴,爲了規範,在重寫對象原型時通常都須要從新給constructor賦值,以保證明例對象的類型不被改寫;

Object.prototype.toString.call() 通用但很繁瑣。

感謝您花時間讀到這裏~

按照慣例,推廣一下微信公衆號「前端麻辣燙」,主要是分享前端知識,着重前端筆試面試知識。歡迎關注~歡迎投稿~

微信搜索微信號:WebSnacks, 或者微信掃碼關注哦!

相關文章
相關標籤/搜索