js中判斷數據類型的4種方法


js中數據類型有8種:

基本數據類型(原始數據類型)(6種):

 number, string, boolean,null, undefined, symbol(es6新增)

引用數據類型:

 object, function

 

1. 最常用方法 -- typeof

缺點: 不能細分對象,數組,時間對象

 typeof 運算符的最終結果有7(typeof null === 'object')

   "number" //   typeof 123 ; typeof NaN
   "string"    //   typeof "123"
   "boolean" //  typeof  true
   "function" //  function f() {}; typeof f
   "object"    //  typeof {}; typeof [];typeof new Date(); typeof null; typeof window  
   "undefined" // typeof undefined; typeof 未定義變量
   "symbol"  // typeof Symbol();

2. 判斷對象類型--instanceof

instanceof 的原理是檢查右邊構造函數的prototype屬性是否在左邊實例對象的原型鏈上。

instanceof(a, B) {// a代表實例對象;b代表構造函數
   a = a.__proto__;
   B = B.prototype;
   while(true) {
      if (a === null) {// 原型鏈頂層
          return false;
      }
      if(a === B) {
         return true;
      }
      a = a.__proto__;
   }
}

instanceof命令本質上調用的是構造函數上的靜態方法[Symbol.hasInstance]。

⚠️:原生的構造函數該方法不能被覆寫。

可以通過在自定義的構造函數上添加靜態方法[Symbol.hasInstance]自定義實現instanceof 命令。  

 

class IsStr{
  static [Symbol.hasInstance](x) {
    return typeof x === 'string';
  }
}
console.log('' instanceof IsStr); //true

所以下面的實例如果 instanceof Object 全部為true

    ([2]) instanceof Array  -> true
    (new Date()) instanceof Date -> true
    (function(){}) instanceof Function  -> true
    ({}) instanceof Object  -> true

    null,undefined 使用該運算法的時候,返回值永遠是 false

三 判斷對象類型 constructor

   constructor屬性的作用是,可以得知某個實例對象,到底是哪一個構造函數產生的。

    constructor屬性是prototype對象上的屬性,實例對象本身沒有這個屬性,調用的是原型對象上的constructor。

    因為js規定P.prototype.constructor === P

    (new Date()).constructor === Date  -> true
    ([2]).constructor === Array -> true
    (function(){}).constructor ===  Function  -> true
    ({}).constructor === Object  -> true

⚠️PS:instanceof 和 constructor 兩者區別:

instanceof考慮的是原型鏈

function A(){};
function B(){};
A.prototype = new B(); // 構造函數A的原型是B的實例
var aobj = new A(); 
console.log(aobj.constructor === B) / //true
console.log(aobj.constructor === A)  //false
console.log(aobj instanceof A)          //true
console.log(aobj instanceof B)          //true 

類不通過prototype屬性進行原型繼承,es6的class中prototype是只讀屬性。

class A {}
Object.getOwnPropertyDescriptor(A, "prototype");
/*
      { 
          "value": constructor,
          "writable": false,
          "enumerable": false,
          "configurable": false 
      }
*/
      class A{};
      class B{};
      A.prototype = new B();
      var aobj = new A(); 
      console.log(aobj.constructor === B)  //false
      console.log(aobj.constructor === A)  //true
      console.log(aobj instanceof A)       //true
      console.log(aobj instanceof B)       //false 

四. 通用方法   

  缺點: 只能判斷原生的數據類型,自定義的無法判斷。

   Object.prototype.toString() 默認返回類型字符串。所有的值都繼承該方法。

   但是數組、字符串、函數、Date 對象都又定義了屬於自己的toString方法,覆蓋了繼承的Object.prototype的toString()方法。

   所以為了可以判斷所有的類型,統一使用Object.prototype.toString.call(value),來判斷數據類型。

   call方法是用於改變this的指向,value就是方法運行時的實例對象,如果value是原始值,會自動將其轉為對應的包裝對象。

  • 數值:返回[object Number]
  • 字符串:返回[object String]
  • 布爾值:返回[object Boolean]
  • undefined:返回[object Undefined]
  • null:返回[object Null]
  • 數組:返回[object Array]
  • arguments 對象:返回[object Arguments]
  • 函數:返回[object Function]
  • Error 對象:返回[object Error]
  • Date 對象:返回[object Date]
  • RegExp 對象:返回[object RegExp]
  • 其他對象:返回[object Object]。 

 *************判斷一個變量是否是對象的方法*************

function isObject(value) {
  return   value === Object(value)
}
// 注意,原始類型的值通過Object()函數之后,會變成對應的包裝對象;
// 對象(數組,對象,函數)等於本身

**************************************************** 

 


免責聲明!

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



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