JavaScript中的類型判斷,瞭解一下?

在前端項目中,誰尚未被對象類型錯誤坑過?前端

typeof操做符

經過typeof操做符獲取操做數的類型:git

typeof undefined; // undefined
  typeof []; // object
  typeof '123'; // string
複製代碼

關於typeof操做符,咱們須要記住兩點,第一點:當操做數爲null時。程序員

typeof null; // object
複製代碼

第二點:當操做數爲原始類型(Primitive)時頗有效,可是對於對象具體類型的判斷每每並非咱們須要的結果。github

Tip: 6大原始類型Null、Undefined、String、Number、Boolean和Symbol。編程

typeof '123'; // string
  typeof new String('123'); // object
複製代碼

Tip: 剛開始學習JS時,常據說:「JS中萬物皆對象」,實際上這裏的萬物並不包含這裏的Primitive Value。app

instanceof操做符

instanceof操做符主要用來檢查構造函數的原型是否在對象的原型鏈上。函數

const s = new String('123');

  s instanceof String; // true
  s instanceof Object; // true
複製代碼

接下來讓咱們搞點事情:工具

s.__proto__ = Object.prototype;

  s instanceof String; // false
  s instanceof Object; // true
複製代碼

利用instanceof操做符,咱們能夠對自定義的對象進行判斷:學習

function Animal (name) {
    this.name = name
  }

  const fizz = new Animal('fizz');

  fizz instanceof Animal // true
複製代碼

constructor屬性

實際上咱們也能夠經過constructor屬性來達到類型判斷的效果:ui

fizz.constructor === Animal // true
複製代碼

可是在實際狀況下,constructor屬性能夠被隨意修改,並且你在原型繼承中,很容易忽略掉constructor的正確指向:

function Rabbit (name) {
    Animal.call(this, name)
  }

  Rabbit.prototype = Object.create(Animal.prototype);
  // 須要手動設置constructor的正確指向
  Rabbit.prototype.constructor = Rabbit;

  const rabbit = new Rabbit('🐰');

  rabbit.constructor === Rabbit // true
複製代碼

從好的編程習慣來講,咱們應該要保持constructor屬性的正確指向。

toString方法

利用toString方法基本上能夠解決全部內置對象類型的判斷:

function type (obj) {
    return Reflect.apply(Object.prototype.toString, obj, []).replace(/^\[object\s(\w+)\]$/, '$1').toLowerCase()
  }
  
  type(new String('123')) // string
複製代碼

可是這種方法對於自定義的構造函數仍然無效。

內置Symbol接口

ES6中經過Symbol暴露了一些內置的API:

Animal.prototype[Symbol.toStringTag] = 'Animal';
  type(rabbit) // animal
複製代碼

如今,咱們能夠經過toString知足全部的需求了,可是也不乏有很皮的程序員:

const o = {
    get [Symbol.toStringTag] () {
      return 'Array'
    }
  }

  type(o) // array
複製代碼

例外對於instanceof操做符也暴露了Symbol.hasInstance,這裏就再也不贅述了。

那些年的坑

這裏就舉一個簡單的例子:

function test (decimal) {
    if (type(decimal) === 'number') {
      return decimal.toFixed(2)
    } else if (type(decimal) === 'string') {
      return parseFloat(decimal).toFixed(2)
    } else {
      return '0.00'
    }
  }

  test(28.39843) // 28.40
  test('323.2321321') // 323.23
複製代碼

用過toFixed()方法的人都知道它是Number.prototype上的方法,若是傳入的並非數字類型,那就會出現各類問題。

固然咱們處於一個前端工具蓬勃發展的時代,涌現了不少靜態類型檢查的工具:


    喜歡本文的小夥伴們,歡迎關注個人訂閱號超愛敲代碼,查看更多內容.

相關文章
相關標籤/搜索