4種JavaScript數據類型判斷的方法

2022-01-09 web前端開發

來源 | https://www.cnblogs.com/echoyya/p/14416375.html今天分享4種JavaScript類型判斷的方法:typeof、instanceof、Object.prototype.toString.call()、constructorJavaScript有八種內置類型,除對象外,其他統稱為基本類型Symbol: 是ES6中引入的一種原始數據類型,表示獨一無二的值。BigInt:是 ES2020 引入的一種新的數據類型,用來解決 JavaScript中數字只能到 53 個二進位位(JavaScript 所有數字都保存成 64 位浮點數,大於這個範圍的整數,無法精確表示的問題。具體可查看:新數據類型 — BigInt1、typeoftypeof是一個操作符而不是函數,其右側跟一個一元表達式,並返回這個表達式的數據類型。返回的結果用該類型的字符串(全小寫字母)形式表示包括以下 8 種:string、number、boolean、undefined、function 、symbol、bigInt、object。對於數組,對象,null以及時間等數據,typeof只能返回object,而不能直接返回對應的類型,還需要通過其他法判斷。
console.log(typeof "");            console.log(typeof 1 );            console.log(typeof NaN );          console.log(typeof true);          console.log(typeof undefined);     console.log(typeof function(){});  console.log(typeof isNaN);         console.log(typeof Symbol());      console.log(typeof 123n);          console.log(typeof []);            console.log(typeof {});            console.log(typeof null);          console.log(typeof new Date());    console.log(typeof new RegExp());  

2、instanceof

instanceof 是用來判斷 A 是否為 B 的實例,表達式為:A instanceof B,如果 A 是 B 的實例,則返回 true,否則返回 false。 需特別注意:instanceof 檢測的是原型

即instanceof 用來比較一個對象是否為某一個構造函數的實例。instanceof可以準確的判斷複雜數據類型,但是不能正確判斷基本數據類型。

console.log(12 instanceof Number);                 console.log('22' instanceof String);               console.log(true instanceof Boolean);              console.log(null instanceof Object);               console.log(undefined instanceof Object);          console.log(function a() {} instanceof Function);  console.log([] instanceof Array);                  console.log({a: 1} instanceof Object);             console.log(new Date() instanceof Date);           

補充:

instanceof 的原理:主要的實現原理就是只要右邊變量的 prototype在左邊變量的原型鏈上即可。
因此,instanceof 在查找的過程中會遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,如果存在返回true 否則返回false

function new_instance_of(leftVaule, rightVaule) {     let rightProto = rightVaule.prototype;     leftVaule = leftVaule.__proto__;     while (true) {      if (leftVaule === null) {            return false;          }        if (leftVaule === rightProto) {            return true;          }         leftVaule = leftVaule.__proto__     }}

注意:instanceof 運算時會遞歸查找leftVaule的原型鏈,即leftVaule.__proto__.__proto__.__proto__.__proto__... 直到找到了或者找到頂層為止。

一句話理解其運算規則:instanceof 檢測左側的 __proto__ 原型鏈上,是否存在右側的 prototype 原型。

3、constructor

JavaScript中,每個對象都有一個constructor屬性,可以得知某個實例對象,到底是哪一個構造函數產生的, constructor屬性表示原型對象與構造函數之間的關聯關係。

當一個函數F被定義時,JS引擎會為F添加prototype原型,然後在prototype上添加一個constructor屬性,並讓其指向F的引用,F利用原型對象的constructor屬性引用了自身,當F作為構造函數創建對象時,原型上的constructor屬性被遺傳到了新創建的對象上,從原型鏈角度講,構造函數F就是新對象的類型。這樣做的意義是,讓對象誕生以後,就具有可追溯的數據類型。

通過typeof運算符來判斷它是原始的值還是對象。如果是對象,就可以使用constructor屬性來判斷其類型。

如判斷數組的函數:

function isArray(data){   return typeof data == "object" && data.constructor == Array; }isArray([])  

注意:null 和 undefined 是沒有 constructor 存在的,這兩種類型的數據需要通過其他方式來判斷。

console.log('22'.constructor === String)             console.log(true.constructor === Boolean)            console.log([].constructor === Array)                console.log(document.constructor === HTMLDocument)   console.log(window.constructor === Window)           console.log(new Number(22).constructor === Number)   console.log(new Function().constructor === Function) console.log(new Date().constructor === Date)         console.log(new RegExp().constructor === RegExp)     console.log(new Error().constructor === Error)       

2、如果修改了原型對象,一般會同時修改constructor屬性,防止引用的時候出錯。所以,修改原型對象時,一般要同時修改constructor屬性的指向。

function Rectangle(width, height){    this.width = width;    this.height = height;    this.getArea = function(){        return '矩形的面積為' + (width * height);    }}
var rect1 = new Rectangle(40, 20);var rect2 = new Rectangle(50, 20);var rect3 = new Rectangle(60, 20);console.log(rect1.getArea());console.log(rect2.getArea());console.log(rect3.getArea());

function Rectangle(width, height){    this.width = width;    this.height = height;}
Rectangle.prototype = { constructor: Rectangle, getArea: function(){ return '矩形的面積為' + (this.width * this.height); }}
Object.defineProperties(Rectangle.prototype, { constructor: { enumerable: false, configurable: false, writable: false }, getArea: { enumerable: false, configurable: false, writable: false }})
var rect1 = new Rectangle(40, 20);var rect2 = new Rectangle(50, 20);var rect3 = new Rectangle(60, 20);console.log(rect1.getArea());console.log(rect2.getArea());console.log(rect3.getArea());

很多情況下,我們可以使用instanceof運算符或對象的constructor屬性來檢測對象是否為數組。

如很多JS框架就是使用這兩種方法來判斷對象是否為數組類型。 但是檢測在跨框架(cross-frame)頁面中的數組時,會失敗。

原因就是在不同框架(iframe)中創建的數組不會相互共享其prototype屬性。例如:

 <script>     window.onload=function(){         var iframe_arr=new window.frames[0].Array;         console.log(iframe_arr instanceof Array);              console.log(iframe_arr.constructor == Array);      }</script>

4、Object.prototype.toString.call()

獲取對象o的class屬性。這是一個內部屬性,

連接字符串:[object + 結果(1)],格式為 [object Xxx] ,其中 Xxx 就是對象的類型。

對於 Object 對象,直接調用 toString() 就能返回 [object Object] 。而對於其他對象,則需要通過 call / apply 來調用才能返回正確的類型信息。

  console.log(Object.prototype.toString.call(1))            console.log(Object.prototype.toString.call(1n))           console.log(Object.prototype.toString.call('123'))        console.log(Object.prototype.toString.call(true))         console.log(Object.prototype.toString.call(undefined))    console.log(Object.prototype.toString.call(null))         console.log(Object.prototype.toString.call({}))           console.log(Object.prototype.toString.call([]))           console.log(Object.prototype.toString.call(function a() {}))    console.log(Object.prototype.toString.call(Symbol()))           console.log(Object.prototype.toString.call(Math))               console.log(Object.prototype.toString.call(JSON))               console.log(Object.prototype.toString.call(new Date()))         console.log(Object.prototype.toString.call(new RegExp()))       console.log(Object.prototype.toString.call(new Error))          console.log(Object.prototype.toString.call(window)              console.log(Object.prototype.toString.call(document))         

封裝一個準確判斷數據類型的函數

  function __getType(object){    return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];  };

可以解決上面的跨框架問題。

  <script>      window.onload=function(){          var iframe_arr=new window.frames[0].Array;          console.log(Object.prototype.toString.call(iframe_arr)))        }</script>

本文完~

學習更多技能

請點擊下方公眾號

相關焦點

  • javascript之常用數據類型及判斷方法
    ,今天,我們來具體重新了解下javascript中的常見數據類型以及他們的判斷方法。根據複雜方式區分javascript數據二.如何判斷當前數據類型呢?可以直接通過:"typeof 具體數據" 進行判斷是什麼類型的數據。
  • JavaScript 數據類型與類型判斷詳解
    JavaScript 數據類型有兩種,分別是基本數據類型和引用數據類型。
  • 經常被面試官考的 JavaScript 數據類型知識你真的懂嗎?
    本篇文章會以一個面試官問問題的角度來進行分析講解js中的數據類型面試官問:說一說javascript中有哪些數據類型?這五種類型統稱為原始類型(Primitive),表示不能再細分下去的基本類型symbol是ES6中新增的數據類型,symbol 表示獨一無二的值,通過 Symbol 函數調用生成,由於生成的 symbol 值為原始類型,所以 Symbol 函數不能使用 new 調用;null 和 undefined 通常被認為是特殊值,這兩種類型的值唯一,就是其本身。
  • 在javascript程式語言中,數據類型boolean的應用場景
    在javascript編程中,數據類型布爾是最常見的一種類型。此種類型邏輯上比較簡單,只有兩個值:true和false。布爾數據類型與計算機底層的電路開與關有著密切的關聯。但是,布爾值true不一定是1,false不一定是0。
  • 【面試說】聊聊JavaScript中的數據類型
    前言❝請講下 JavaScript 中的數據類型?❞前端面試中,估計大家都被這麼問過。答:Javascript 中的數據類型包括原始類型和引用類型。其中原始類型包括 Null、Undefined、Boolean、Number、String、Symbol、BigInt。
  • 4種JavaScript中不同迭代對象的方法
    英文 | https://javascript.plainenglish.io/javascript-basics-4-different-ways-to-iterate-over-an-object-a5d16335cef
  • 七天學會javascript第一天javascript介紹
    javascript介紹javascript數據類型javascript運算符javascript對象javascriptjs定義變量javascript數據類型1 數據類型:字符串:必須要括在""/''之內的。
  • JavaScript數據類型轉換
    雖然變量的數據類型是不確定的,但是各種運算符對數據類型是有要求的。如果運算符發現,運算子的類型與預期不符,就會自動轉換類型。本文主要介紹數據類型強制轉換和自動轉換,自動轉換是基於強制轉換之上。強制轉換主要指使用Number、String和Boolean三個函數,手動將各種類型的值,分布轉換成數字、字符串或者布爾值。
  • 2.5 JavaScript數據類型的轉換
    JavaScript是一種弱類型的程式語言,使用時無須指定數據類型。但在對表達式進行求值時,通常需要所有的操作數都屬於某種特定的數據類型。例如,進行算術運算時要求操作數都是數值類型,進行字符串連接運算時要求操作數都是字符串類型,而進行邏輯運算時則要求操作數都是布爾類型,這就需要數據類型之間的轉換。
  • 4 種在JavaScript中編寫For循環的方法
    ways-to-write-for-loops-in-javascript-d0db6aa8f7b6這些年來,JavaScript 發展得如此之快。如果你之前有其他程式語言經驗的話,你可能無法相信在 JavaScript 中有4種方法可以編寫for 循環。正如黑格爾所說:「存在就是合理的。」在技術演進的過程中,網絡的力量越來越強大。因此,對於現代 Web 開發的必然語言JavaScript 期望也越來越高。for 循環的語法就是一個很好的例子。開發人員發現老式不夠好,至少對於每個使用場景。一些第三方庫或框架開始提供一些更好的循環功能。
  • 從 JavaScript 到 TypeScript - 聲明類型
    不過仍然有一種類型相關的特性不得不提——泛型。如果只是說數據類型,純粹的 JSer 們還可以理解,畢竟類型不是新鮮玩意兒,只是擴展了點種類。但是泛型這個東西,純粹的 JSer 們可能就沒啥概念了。類型就簡述到這裡,簡單的類型一看就能明白,高級一點的類型我們以後再開專題來詳述。不過既然選擇使用 TypeScript,必然會用到它的靜態類型特性,那就必須強化識別類型的意識,並養成這樣的習慣。對於純 JSer 來說,這是一個巨大的挑戰。聲明類型聲明類型,主要是指聲明變量/常量,函數/方法和類成員的類型。
  • 模擬技術的3種類型放大器基本判斷方法
    打開APP 模擬技術的3種類型放大器基本判斷方法 發表於 2019-06-11 14:19:39 應用情況 (1)3种放大器中,共發射極放大器應用最為廣泛,在各種頻率的放大系統中都有應用,是信號放大的首選電路。
  • 【JavaScript 教程】數據類型-函數
    由於函數與其他數據類型地位平等,所以在 JavaScript 語言中又稱函數為第一等公民。length屬性提供了一種機制,判斷定義時和調用時參數的差異,以便實現面向對象編程的」方法重載「(overload)。2.3、toString()函數的toString方法返回一個字符串,內容是函數的源碼。
  • JavaScript複合數據類型–Object類型
    ,是一種比較複雜的複合數據類型。它本質上包含了部分數據類型,比如數組、函數數據類型、DOM其實等都屬於Object對象。對象可以通過執行new操作符後跟要創建的對象類型的名稱來創建。而創建Object類型的實例並為其添加屬性或方法,就可以自定義對象,如下所示:  這個語法其實和Java中創建對象的語法類似;不過在ECMAScript中,對象創建有個特點,如果不需要傳入參數的話,則可以省略後面的括號。
  • 你必須要知道的JavaScript數據結構與面試題解答
    畢竟,我們組織數據的方式對性能和可用性有很大影響。實際上,大多數頂級公司都需要對數據結構有深刻的了解。這些技能證明你知道如何有效地管理數據。任何想要破解編碼面試的人都需要掌握數據結構。JavaScript具有原始和非原始數據結構。原始數據結構和數據類型是程式語言固有的。這些包括布爾值,空值,數字,字符串等。非原始數據結構不是由程式語言定義的,而是由程式設計師定義的。
  • JS中數據類型的判斷
    面試季馬上就要過去了,很多小夥伴也是在努力的抓住金九銀十的小尾巴,今天來說一說面試中常見的一個問題:js中如何判斷數據類型?眾所周知,JavaScript是一門弱類型的語言,它允許不兼容的類型進行運算,但有些場景使得我們不得不對數據類型做一個規範,如此就需要對數據類型進行判斷。可能你會回答,我一般用typeof來進行判斷,可是面試官會問你,那如果遇到值為null的情況下typeof會返回什麼?
  • 收藏|Java獲取文件類型的5種方法
    我是:小職(z_zhizuobiao)找我:✅ 解鎖高薪工作 ✅ 免費獲取乾貨教程工作中經常會用到,判斷一個文件的文件類型,這裡總結一把,一般判斷文件類型的原理有2種方式:1. 根據文件擴展名判斷2.它調用每個實現的 probeContentType來解析類型。但是,其默認實現是特定於作業系統的,並且可能會失敗,具體取決於我們使用的作業系統。結論:根據文件擴展名判斷。URLConnection提供了幾種用於檢測文件的MIME類型的API。
  • JavaScript
    2.1997 年,ECMA (歐洲計算機製造商協會),制定出客戶端腳本語言的標準:ECMAScript,統一了所有客戶端腳本語言的編碼方式 javascript組成: 1、ECMAscript javascript的語法(變量、函數、循環語句等語法) 2、DOM 文檔對象模型 操作html和css的方法 3、BOM 瀏覽器對象模型 操作瀏覽器的一些方法
  • JavaScript是什麼
    完成與後臺處理程序數據交互。【1.發請求{要} 2.處理數據】簡單的具體操作:1.直接向html文件中寫出標記和內容。2.對事件的反應3.改變 HTML 內容4.改變 HTML 圖像5.改變 HTML 樣式6.驗證輸入
  • JavaScript 基礎語法
    4.3 調試方法 - 文檔方法文檔命令:document.write("在文檔中列印信息"); document.writeln("在文檔中列印信息");write與writeln的區別:write()與writeln()方法類似,只是writeln每個表達式之後多寫一個換行符(\n)4.4 調試命令 - 控制臺命令