選擇適合的類型判斷方式

来源:https://www.cnblogs.com/shapeY/archive/2018/12/24/10168989.html
-Advertisement-
Play Games

類型判斷是個常見問題,有多種不同的判斷方式,每種方式都有適用的場景。 typeof 操作符返回一個字元串,表示未經計算的操作數的類型。 或者 都可以,括弧為可選的。 類型 | 結果 : |: : Undefined | "undefined" ==Null== | =="object"== Bool ...


類型判斷是個常見問題,有多種不同的判斷方式,每種方式都有適用的場景。

typeof

typeof 操作符返回一個字元串,表示未經計算的操作數的類型。

typeof operand 或者 typeof (operand) 都可以,括弧為可選的。

類型 結果
Undefined "undefined"
==Null== =="object"==
Boolean "boolean"
Number "number"
String "string"
Symbol(ECMAScript 6 新增) "symbol"
==函數對象== =="function"==
任何其他對象 "object"

typeof 會將 nullObject 都返回為 "object", 這樣就無法區分具體的對象類型(Array , Date , Error等)。

註意:其中函數對象特別返回為"function" 。

    // 'number'
    typeof 1
    typeof NaN
    typeof Infinity    
    
    // 'string'
    typeof '1'
    
    // 'boolean'
    typeof true
    
    // 'undefined'
    typeof undefined
    
    // 'symbol'
    typeof Symbol(1)
    
    // 'object'
    typeof null
    
    // 'object'
    typeof {}
    typeof []
    typeof new Date()
    typeof new Number(1)

    // 'function'
    typeof function(){}
    typeof class A {}
    typeof Math.sin

instanceof

instanceof運算符用於測試構造函數的prototype屬性是否出現在==對象==的原型鏈中的任何位置

object instanceof constructor

  • 左側參數如果不是對象,將返回false
  • 右側參數如果不是構造函數,將報錯
    let x = 1;
    let y = new Number(1);
    
    x instanceof Number // false   1 不是對象
    y instanceof Number // true  new Number(1)為對象

    // 雖然這種方式測試“x”有原型,但是應該是在獲取的時候,自動進行了對象包裝, 其實獲取的是 new Number(1)
    x.__proto__ === Object.getPrototypeOf(x) === Number.prototype 

    // 沿著原型鏈比對  y.__proto__.__proto__ === Object.prototype , 故返回true
    y instanceof Object // true

instanceof 的判斷結果會隨著對象或者構造函數的改變而不同,而不是固定的值

    class A {}
    class B {}
    let a = new A();

    a instanceof A  // true
    a instanceof B  // false

    // 修改a的 __proto__ 指向
    a.__proto__ = B.prototype

    a instanceof A  // false
    a instanceof B  // true

instanceof不能判斷原始數據類型,但是可以用來判斷對象具體是那種類型


    [] instanceof Array // true
    new Error() instanceof Error // true
    (/[1-9]+/) instanceof RegExp // ture
    new Date() instanceof Date // true

    let x = document.querySelectorAll('h1')
    x instanceof NodeList // true
    ···

Object.prototype.toString()

toString()方法返回一個表示該對象的字元串。預設情況下,toString()方法被每個Object對象繼承。如果此方法在自定義對象中未被覆蓋,toString() 返回 "[object type]" ,其中type是對象的類型

待檢測對象也許會重寫toString()方法,這時就無法檢測toString來判斷類型。所以要保證能夠檢測類型,需要調用Object.prototype.toString來進行判斷。如下:

    let X = function(x) {
        this.name = x
    }

    let x =  new X(); 

    x.toString() // "[object,Object]"  使用繼承的toString
    Object.prototype.toString.call(x) // "[object,Object]"

    X.prototype.toString = function() { // 重寫父類的toString方法
        return 'not type'
    }

    x.toString() // "not type"   使用重寫後的toString , 就不再返回類型

    Object.prototype.toString.call(x) // "[object,Object]"

返回的" [ object, Type]" 不好分辨,可以進行特殊的處理,直接返回類型名稱。

    // 獲取類型
    function getType(target){
        let types = {}
        let temp = Object.prototype.toString.call(target)
        //types映射類型
        'Boolean Number String Null Undefined Symbol Function Array Date RegExp Object Error NodeList'.split(' ').map(value => {
            types[`[object ${value}]`] = value.toLowerCase()
        })

        if (types[temp]) {
            return types[temp]
        }else if (temp.indexOf('HTML') !== -1) { // 判斷是否為DOM元素
            return 'element' 
        }else {
            return
        }
    }
    
    // 測試

    getType(1) //  "number"
    getType(Symbol(1)) // "symbol"
    getType([]) // "array"
    getType({}) // "object"
    getType(document.querySelectorAll('div')) // "nodelist"

用如上方法,就可以便捷的獲取到類型名稱了。

其他API

判斷值是否是 NaN Number.isNaN()

Number.isNaN() 判斷值是否是 NaN,和全局函數 isNaN() 相比,該方法不會強制將參數轉換成數字,只有在參數是真正的數字類型,且值為 NaN 的時候才會返回 true。

    Number.isNaN(NaN);        // true
    Number.isNaN(Number.NaN); // true
    Number.isNaN(0 / 0)       // true
    
    Number.isNaN(null);       // false
    Number.isNaN(37);         // false
    Number.isNaN("37");       // false

    Number.isNaN("NaN");      // false 不會隱式轉換
    window.isNaN('NaN')       // true 會隱式轉換

判斷值是否為有窮數 Number.isFinite()

Number.isFinite() 方法用來檢測傳入的參數是否是一個有窮數(finite number)。 和全局的 isFinite() 函數相比,這個方法不會強制將一個非數值的參數轉換成數值,這就意味著,只有數值類型的值,且是有窮的(finite),才返回 true

    Number.isFinite(Infinity);  // false
    Number.isFinite(NaN);       // false
    Number.isFinite(-Infinity); // false

    Number.isFinite(0);         // true
    Number.isFinite(2e64);      // true

    Number.isFinite('0');       // false, 全局函數 isFinite('0') 會返回 true

判斷值是否為整數 Number.isInteger()

Number.isInteger() 方法用來判斷給定的參數是否為整數。

    Number.isInteger(0);         // true
    Number.isInteger(1);         // true
    Number.isInteger(-100000);   // true

    Number.isInteger(0.1);       // false
    Number.isInteger(Math.PI);   // false

    Number.isInteger(Infinity);  // false
    Number.isInteger(-Infinity); // false
    Number.isInteger("10");      // false 不會進行隱式轉換
    Number.isInteger(true);      // false
    Number.isInteger(false);     // false
    Number.isInteger([1]);       // false

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在vue中會出現一種情況 const url=this.$route.query.returnURL; this.$router.push(url); $router和$route的區別傻傻的分不清 1.先說$router這個就是router的實例, 在創建vueRouter實例 const rou ...
  • 我們知道,想要手動觸發blur事件時候,可以使用:https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur 然而在react中,當你想手動觸發一個input的blur事件時,你會得到一個錯誤:blur is not a fun ...
  • 獲取當前頁面的地址欄。與導航欄中所有<a> 標簽的href屬性 進行比較。如果相等則高亮顯示 此<a>標簽。 註意點:a 標簽的href 屬性在瀏覽器解析時 是絕對路徑。 a 標簽的href 如果是錨點,則 pathname , href都與 location的 pathname ,href相等,但 ...
  • 發送ajax請求,獲取數據。判斷code狀態。通過模板引擎渲染的頁面。根據服務端數據的總條數判斷是否 顯示載入更多 按鈕。 代碼 ...
  • 目標效果:點擊標簽1,如果列表標簽的style的display是block,改成none,否則改成block,來達到展開收縮菜單效果 一.準備階段 html文件 運行後頁面效果 二.:點擊標簽1隱藏列表 方法1 html代碼 效果從上圖到下圖 方法2 方法3 方法4 在方法4基礎上加上if判斷就可以 ...
  • 背景 開發一個圖片上傳功能 需求要用vant中的Uploader , 發現 Uploader組件官方封裝返回的數據是加密的,不適合我這個項目(需要上傳到本地ftp伺服器), 看了一下官方 issue 發現有人提問 官方有回覆 加密數據轉 formdata格式的操作, 複製過來發現不行,又搜索了一下度 ...
  • https://wisdmlabs.com/blog/create-adaptive-placeholders-using-css/ https://circleci.com/blog/adaptive-placeholders/ https://stackoverflow.com/question ...
  • 前言 最近在做vue移動端項目,需要做一個可以固定表頭首列的表格,而且由於一些原因不能使用任何UI插件,網上找了很久也沒什麼好方法,所以在解決了問題之後,寫下了這篇文章供後來人參考,文章有什麼錯漏的問題歡迎評論交流。 效果 思路 要實現固定首行首列 除了使用各種UI框架插件外,那就是自己用原生寫啦 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...