js 數據類型及檢測


js中基本數據類型有6種number、string、undefined、null、boolean,Symbol (ES6 新增,表示獨一無二的值),還有一種數據類型為引用數據類型統稱為Object對象,其中包括常見的Arry(數組)、Function(函數)、Date等,

  基本數據類型

1、值是不可變的

    var a='apple';
    var b=a.toUpperCase();
    console.log(a)    //apple
    console.log(b)    //APPLE

2、基本數據類型直接存放在棧中,占據空間、大小固定,屬於被頻繁使用的,所以放入棧中存儲。

引用數據類型

1、值是可以變的

    var a={
        name:"yuan",
        sex:"man"
    };
    a.name='zhi';
    console.log(a)    //{name: "zhi", sex: "man"}

2、同時保存在棧和堆中

引用數據類型數據一般比較大、結構比較復雜,如果存儲在棧中會影響到程序的性能,所以分為兩部分指針和實體,指針類似地址名片記錄着數據存放的實際位置,存放於棧中,實體就是數據的實際起始地址。存放在堆中,使用的時候解釋器獲得指針地址后去堆中找到相對應的數據。

因為這種結構,所以引用數據類型的直接賦值是指針的賦值,指向的都是同一個實體對象,所以通過某一個指針修改,存放於堆中的實體對象都會發生改變。

    var a={
        name:"yuan",
        sex:"man"
    };
    var b=a;
    b.name='zhi';    
    console.log(a)    //{name: "zhi", sex: "man"}
    console.log(b)    //{name: "zhi", sex: "man"}

數據類型的判斷(原生js)

1、typeof

這是最基本的一個判斷方式,該操作符返回一個表示數據類型的字符串,共有7種結果:number、string、boolean、object、function、undefined、symbol。很明顯它不能區分引用數據類型里面的數組等對象(包括null);

    var a=[1,2,3];
    var b=null;
    console.log(typeof a)    //object
    console.log(typeof b)    //object

2、instanceof

instanceof是用來判斷A是否為B的實例,表達式:A instanceof B;如果A是B的實例則返回true,否則返回false;instanceof運算符是通過判斷該對象在原型鏈上是否存在一個構造函數的prototype屬性;

    var a=[1,2,3];
    var b=new Date();
    console.log(a instanceof Array)    //true
    console.log(b instanceof Date)    //true

依上面所說這將主要涉及js中非常重要的原型鏈繼承機制,這里就不詳細說了,簡單來說在 JavaScript 原型繼承結構里面,規范中用 [[Prototype]] 表示對象隱式的原型,在 JavaScript 中用 __proto__ 表示,並且在 Firefox 和 Chrome 瀏覽器中是可以訪問得到這個屬性的,但是 IE 下不行。所有 JavaScript 對象都有 __proto__ 屬性,但只有 Object.prototype.__proto__ 為 null,前提是沒有在 Firefox 或者 Chrome 下修改過這個屬性。這個屬性指向它的原型對象。 至於顯示的原型,在 JavaScript 里用 prototype 屬性表示,這個是 JavaScript 原型繼承的基礎知識。

根據相關規范和網上例子寫一個instanceof:

    function instance_of(L, R) {//L 表示左表達式,R 表示右表達式
        var O = R.prototype;// 取 R 的顯示原型
        L = L.__proto__;// 取 L 的隱式原型
        while (true) {
            if (L === null)
                return false;
            if (O === L)// 這里重點:當 O 嚴格等於 L 時,返回 true
                return true;
            L = L.__proto__;
        }
    }
    var a=[1,2,3];
    var b=new Date();
    console.log(instance_of(a,Array))    //true
    console.log(instance_of(b,Date))    //true

instanceof也具有以下三點的不足:

1、不能檢測null和undefined

    console.log(instance_of(null instanceof null))
    console.log(instance_of(undefined instanceof undefined))

對於特殊的數據類型 null 和 undefined,他們的所屬類是 Null 和 Undefined,但是瀏覽器把這兩個類保護起來了,不允許我們在外面訪問使用。

2、通過構造函數實例化和字面量生成的基本類型判斷是有一定區別的

    var a=123;
    var b=new Number(123)

    console.log(a instanceof Number)    //false
    console.log(b instanceof Number)    //true

為什么會這樣呢?嚴格意義上講只有實例創建出來的數據才是標准的對象數據類型值,也是標准的 Number 這個類的一個實例;對於字面量方式創建出來的結果是基本的數據類型值,不是嚴謹的實例,但是由於 JS 的松散特點,導致了可以使用 Number.prototype 上提供的方法。

3、constructor

constructor和prototype 非常相似,但 constructor 檢測 Object 與 instanceof 不一樣,還可以處理基本數據類型的檢測。

    var a=123;
    var b=new Number(123)

    console.log(a.constructor==Number)    //true
    console.log(b.constructor==Number)    //true

constructor具有以下兩點不足

1、null 和 undefined 是無效的對象,因此是不會有 constructor 存在的,這兩種類型的數據需要通過其他方式來判斷。

2、函數的 constructor 是不穩定的,這個主要體現在把對象的原型進行重寫,在重寫的過程中很有可能出現把之前的 constructor 給覆蓋了,這樣檢測出來的結果就是不准確的。

    function Fn() {

    }
    Fn.prototype=new Array();

    var a=new Fn();
    console.log(a.constructor==Array)    //true

4、Object.prototype.toString.call()

這個是最准確最常用的方式,首先獲取Object上面的toString方法,方法執行時讓里面的this指向第一個參數的值。

關於toString:

  • 本意是轉換為字符串,但是某些 toString 方法不僅僅是轉換為字符串對於 Number、String,Boolean,Array,RegExp、Date、Function 原型上的 toString 方法都是把當前的數據類型轉換為字符串的類型(它們的作用僅僅是用來轉換為字符串的)

  • 對於 Number、String,Boolean,Array,RegExp、Date、Function 原型上的 toString 方法都是把當前的數據類型轉換為字符串的類型(它們的作用僅僅是用來轉換為字符串的)
  • Object 上的 toString 並不是用來轉換為字符串的

Object 上的 toString 它的作用是返回當前方法執行的主體(方法中的 this)所屬類的詳細信息即"[object Object]",其中第一個 object 代表當前實例是對象數據類型的(這個是固定死的),第二個 Object 代表的是 this 所屬的類是 Object。

    console.log(Object.prototype.toString.call(123))    //[object Number]

    console.log(Object.prototype.toString.call(null))    //[object Null]
    console.log(Object.prototype.toString.call({}))    //[object Object]
    console.log(Object.prototype.toString.call(undefined))    //[object Undefined]
    console.log(Object.prototype.toString.call('123'))    //[object String]

 最后貼個圖總結一下(來自網絡)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM