js的基本類型、引用類型、包裝類型

最近重溫JS高程設計以及與朋友的討論。決定趁熱打鐵記錄JS的各類類型,並作下深刻總結。面試

js的幾種類型

  1. 基本類型:Boolean、String、Number、Null、Undefined
  2. 引用類型:
    2.1 Object、Array、Date、RegExp等
    2.2 基本包裝類型:Boolean、String、Number

基本類型

就是咱們日常用來作簡單賦值的類型。這種數據類型是存在棧中以值得形式存在,賦值時也是直接進行值傳遞segmentfault

引用類型

是高級的類型,能夠添加方法和熟悉等。真正的數據存在堆中,賦值時是進行址傳遞數組

//舉個例子
    var a = [3,4,5];
    var b = a;//賦值的是 存儲 a變量的地址。這時候a、b指向同一片內存區域
    b[0] = 9;//改變內存區域中的值 a的值也進行更改
    console.log(a);//[9,4,5]

基本包裝類型介紹

咱們都知道只有引用類型才能添加、調用屬性和方法,那爲何基本類型Boolean、String、Number能調用方法?按說它是沒有方法纔對呀!這是由於ECMAScript提供了三個特殊的包裝類型:Boolean、String、Number。每當讀取這個基本類型時,後臺會建立一個對應的基本包裝類型的對象。使得能夠操做這個基本類型了。prototype

當咱們在內存中讀取基本類型時,後臺會作如下操做:

1.建立對應包裝類型(Boolean、String、Number)的實例
2.在實例上調用對應的方法
3.銷燬這個實例
//舉個實際操做的例子  
    var str = 'have a good time';
    var str2 = str.charAt(0);//h;
    str.color = 'red';
    console.log(str.color);//undefined

這是由於引用類型和基本包裝類型的生存期不同。引用類型在執行流離開當前做用域時一直存在內存中。自動建立的基本包裝類型的對象,只存在於執行這一行代碼的一瞬間,執行完立馬被銷燬了。這就是爲何咱們給str.color添加對象時打印出來爲undefined。由於在執行完str的color這一行代碼時,自動建立的包裝類型對象被銷燬了。下面console出來的str是新建立的String對象,沒有color這個屬性。設計

js類型判斷

  1. typeof 主要是用來判斷基本數據類型code

    //返回類型: string、number、boolean、object、undefined、function、Symbol(ES6新增)
    typeof 123; // "number"
    typeof 'cherry';// "string"
    typeof false; //"boolean"
    typeof undefined; //"undefined"
    typeof null; // "object"
    typeof {name:"cherry"};//"object"
    var fun = function(){};
    typeof fun; //"function"
    typeof new String('xxx');//"object"

    因此typeof只能用來判斷基本數據類型。null、引用類型、基本包裝類型都會返回object。對象

  2. instanceof 用法:A instanceof B,主要是判斷A是不是某個對象的實例,簡單來講就是A的原型鏈上(__proto__)是否有B的原型對象(prototype)。ip

    // 例子
    var obj= {"name":"cherry"};
    obj instanceof Object; //true
    
    var strObj = new String('hello');
    strObj instanceof String;//true
    
    var str = 'hello';
    str instanceof String;//false
    //判斷的原理 就是計算逐級計算左邊對象的__proto__是否等於右邊對象的prototype便可
    function instance(left,right){
        var obj = right.prototype;
        var left = left.__proto__;
        while(true){
            if(left === null){
                return false;
            }
            if(left == obj){
                return true;
            }
            left = left.__proto__;
        }
    }
  3. Object.prototype.toString.call()(點擊看此方法具體原理)
    Object.toString()返回對象的字符串表示。可是因爲數值、布爾、字符串、數組都有重寫toString方法,直接調用的時候使用的是自身原型對象上有toString方法則不會往上去找Object的toString方法。這裏強制使用Object原型對象上的toString方法。內存

    Object.prototype.toString.call('123');//[object String]
    var objStr = new String('123');//包裝類型檢測出來也是對應類型而不是對象
    Object.prototype.toString.call(objStr);//[object String]
    Object.prototype.toString.call(123);//[object Number]
    Object.prototype.toString.call(true);//[object Boolean]
    Object.prototype.toString.call(null);//[object Null]
    Object.prototype.toString.call(undefined);//[object Undefined]
    var obj = {"name":"cherry"};
    Object.prototype.toString.call(obj);//[object Object]
    var arr = [1,2,3];
    Object.prototype.toString.call(arr);//[object Array]

    總結:使用Object的toString(),能夠檢測出各值的類型。基本數據類型和基本包裝類型返回的值是同樣。因此不用擔憂別人是經過基本包裝類型定義的變量(面試時被問過)原型鏈



    面試題:判斷一個值的數據類型

    function valueType(data){
        var type = null;
        var typeList = ['Object','Number','Boolean','String','Function','Object','Null','Undefined'];
        for(var item of typeList){
            if(Object.prototype.toString.call(str) == `[object ${item}]`){
                type = item;
                break;
            }
        }
        return type;
    }
相關文章
相關標籤/搜索