JS中檢測數據類型的幾種方式及優缺點

来源:http://www.cnblogs.com/allenlei/archive/2016/12/11/6161022.html
-Advertisement-
Play Games

1、typeof 用來檢測數據類型的運算符 typeof value 返回值首先是一個字元串,其次裡面包含了對應的數據類型,例如:"number"、"string"、"boolean"、"undefined"、"object"、"function" 局限性:1)typeof null ->"obje ...


1、typeof 用來檢測數據類型的運算符

typeof value 返回值首先是一個字元串,其次裡面包含了對應的數據類型,例如:"number"、"string"、"boolean"、"undefined"、"object"、"function"

局限性:
1)typeof null ->"object"
2)檢測的不管是數組還是正則都返回的是"object",所以typeof不能判斷一個值是否為數組

console.log(typeof [12, 23]);//->"Object"

 

2、instanceof/constructor

檢測某一個實例是否屬於某一個類
使用instanceof/constructor可以檢測數組和正則

console.log([] instanceof Array);//->true
console.log(/^$/ instanceof RegExp);//->true
console.log([] instanceof Object);//->true

console.log([].constructor === Array);//->true
console.log([].constructor === Object);//->false

constructor可以避免instanceof檢測數組的時候,用Object也是true的問題

console.log({}.constructor === Object);//true
console.log([].constructor === Object);//false

 

局限性:

 

1)用instanceof檢測的時候,只要當前的這個類在實例的原型鏈上(可以通過原型鏈__proto__找到它),檢測出來的結果都是true

var oDiv = document.getElementById("div1");
//HTMLDivElement->HTMLElement->Element->Node->EventTarget->Object
console.log(oDiv instanceof HTMLDivElement);//->true
console.log(oDiv instanceof Node);//->true
console.log(oDiv instanceof Object);//->true  

 

2)基本數據類型的值是不能用instanceof來檢測的

console.log(1 instanceof Number);//->false

數組創建的兩種方式(對象、正則、函數...)
對於引用數據類型來說,我們兩種方式創建出來的都是所屬類的實例,而且都是對象數據類型的值,是沒有區別的

var ary = [];
var ary = new Array;

對於基本數據類型來說,雖然不管哪一種方式創建出來的都是所屬類的一個實例(在類的原型上定義的方法都可以使用),但是字面量方式創建出來的是基本數據類型,而實例方式創建出來的是對象數據類型

var num1 = 1;
var num2 = new Number("1");
console.log(typeof num1,typeof num2);//->"number" "object"  

 

3)在類的原型繼承中,instanceof檢測出來的結果其實是不准確的

function Fn() {}
var f = new Fn;
console.log(f instanceof Array);//->false f不是一個數組,它就是一個普通的實例(普通的對象)

雖然Fn繼承了Array,但是f沒有length和數字索引哪些東西,所以f應該不是數組才對,但是用instanceof檢測的結果卻是true,因為f雖然不是數組,但是在f的原型鏈上可以找到Array

function Fn() {
}
Fn.prototype = new Array;//->Fn子類繼承了Array這個父類中的屬性和方法
var f = new Fn;
console.log(f instanceof Array);//->true

  

3、Object.prototype.toString.call(value) ->找到Object原型上的toString方法,讓方法執行,並且讓方法中的this變為value(value->就是我們要檢測數據類型的值)

Object.prototype.toString常用來判斷對象值屬於哪種內置屬性,它返回一個JSON字元串——"[object 數據類型]"。

由於許多引用類型都重寫了Object繼承來的的toStrong方法,所以我們通常使用call或者apply借用Object.prototype.toString函數來判斷數據類型。

當然,這樣調用的預設前提是Object.prototype.toString沒有被重寫。

toString:一個方法,轉換為字元串數據類型用的方法
每一個數據類型所屬類的原型上都有toString方法,例如:Number.prototype/String.prototype/Array.prototype/Function.prototype...
除了Object上的toString,其他類原型上的toString都是把當前的數據值轉換為字元串的意思

null和undefined比較的特殊:他們所屬類Null/Undefined的原型上也有toString,只不過不讓我們用而已,不僅如此其實類的原型都給屏蔽了

HTML元素對象的toString:雖然它的原型鏈很長,但是在其它類的原型上都沒有toString,只有在最底層Object.prototype這上才有

var oDiv = document.getElementById("div1");
oDiv.toString(); //->調用的其實也是Object.prototype.toString...

//alert、document.write 這兩種輸出的方式其實都是把要輸出的內容先轉換為字元串,然後再輸出的
alert([]); //->"" alert(true); //->"true" alert({}); //->這個就要調用Object.prototype上的toString了 ->"[object Object]"

 

//定義toString變數是為了簡便書寫,同時降低作用域鏈檢索的性能損耗
var toString = Object.prototype.toString;
console.log(toString.call(1));//[object Number]
console.log(toString.call(undefined));//[object Undefined]
console.log(toString.call(null));//[object Null]
console.log(toString.call(false));//[object Boolean]
console.log(toString.call("s"));//[object String]
console.log(toString.call({}));//[object Object]
console.log(toString.call(/[a]/g));//[object RegExp]
console.log(toString.call(function(){}));//[object Function]

 

is系列函數的簡易實現

在明白數據類型怎麼檢測後,下麵我們來簡單實現is系列檢測函數。

var dataType = {
        '[object Null]' : 'null',
        '[object Undefined]' : 'undefiend',
        '[object Boolean]' : 'boolean',
        '[object Number]' : 'number',
        '[object String]' : 'string',
        '[object Function]' : 'function',
        '[object Array]' : 'array',
        '[object Date]' : 'date',
        '[object RegExp]' : 'regexp',
        '[object Object]' : 'object',
        '[object Error]' : 'error'
    },
    toString = Object.prototype.toString;

function type(obj) {
    return dataType[toString.call(obj)];
}

//生成is系列函數
function createValidType() {
    for(var p in dataType) {
        var objType = p.slice(8, -1);
        (function(objType) {
            window['is' + objType] = function(obj) {
                return type(obj) === objType.toLowerCase();
            }
        })(objType)
    }
}
createValidType();

console.log(isObject({}));//true
console.log(isDate(new Date()));//true
console.log(isBoolean(false));//true
console.log(isString(1));//false
console.log(isError(1));//false
console.log(isError(new Error()));//true
console.log(isArray([]));//true
console.log(isArray(1));//false

上面代碼里分別實現了isNull、isUndefined、isBoolean、isNumber、isString、isFunction、isArray、isDate、isRegExp、isObject、isError這11個檢測函數。同時也實現了type函數,用以檢測數據類型。

console.log(type({}));//"object"
console.log(type(new Date()));//"date"
console.log(type(false));//"boolean"
console.log(type(1));//"number"
console.log(type(1));//"number"
console.log(type(new Error()));//"error"
console.log(type([]));//"array"
console.log(type(1));//"number"

createValidType函數巧用閉包保存數據狀態的特性,批量生成is系列函數。


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

-Advertisement-
Play Games
更多相關文章
  • os:mac, django1.9.5, python3.5 database:mysql 0.背景 django內置的database如下: 要註意的是無論選擇使用哪個資料庫伺服器,都必須下載和安裝對應的資料庫適配器 1.安裝 我們選擇mysql作為資料庫伺服器 因為MySQLdb並不支持Pyth ...
  • Problem 1 - Time Limit : 1s Memory Limit : 512M Code Limit : 128KDescription我們定義階乘N!=1×2×3×...×N,並且0!=1。現在我們想知道對於N!的階乘結尾總共有多少個0。Input一行一個整數N。Output0的個 ...
  • ...
  • 實現多態的前提 1。 要有繼承 2。 要有方法重寫,沒有也可以,但是沒有的話 就沒有意義 3。 要有父類引用 指向子類對象 如: 父類 f=new 子類(); * 多態中的成員訪問特點 * A, 成員變數 編譯看左邊, 運行看左邊 * B, 構造方法 創建子類對象的時候,,訪問 父類的構造方法, 對 ...
  • 推薦大家可以看看這個:http://wenku.baidu.com/link?url=RQU2exzV_EF3GATc3bzQU2o9LGMuCmiN5nUJth5SLG3E2TrxtBLQodJU_kZgfJjd9ljtR5XhZlHdzoHJ6kLeAF4uC9dttM1sNer60lg09gS ...
  • 功能強大的 jQuery 表單驗證插件,適用於日常的 E-mail、電話號碼、網址等驗證及 Ajax 驗證,除自身擁有豐富的驗證規則外,還可以添加自定義的驗證規則。 相容 IE 6+, Chrome, Firefox, Safari, Opera 10+ 版本: jQuery v1.7+ jQuer ...
  • CSS不像其它高級語言一樣支持算術運算、變數、流程式控制制與面向對象特性,所以CSS樣式較多時會引起一些問題,如修改複雜,冗餘,某些別的語言很簡單的功能實現不了等。而javascript則是一種半面向對象的動態語言,有java的影子,有C的味道,中間有比其它語言多的糟粕,使用預處理辦法可以解決這些問題。 ...
  • 本文主要說明Json的基本概念,和一個在Html中使用Json給元素賦值的小例子,屬於基礎性信息 什麼是 JSON ? JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation) JSON 是輕量級的文本數據交換格式 JSON 獨立於語言 * JSON ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...