狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

厲害了!這是JavaScript中的數據類型判斷方法最全總結

admin
2024年4月19日 18:5 本文熱度 805
01
前言


在 JavaScript 中,主要有七種基本數據類型Undefined、Null、Boolean、Number、String、Symbol、BigInt,還有一種復雜數據類型Object,其中包含了Data、function、Array、RegExp等。JavaScript 不支持任何創建自定義類型的機制,而所有值最終都將是上述8種數據類型之一。由于JavaScript 是一種動態類型語言,這意味著你可以在程序執行過程中改變變量的類型。

基本數據類型與引用數據類型的區別:基本數據類型是指存放在棧(stack)中的簡單數據段,數據大小確定,內存空間大小可以分配,它們是直接按值存放的,所以可以直接按值訪問引用類型是存放在堆(heap)內存中的對象,變量其實是保存的在棧內存中的一個指針(保存的是堆內存中的引用地址),這個指針指向堆內存。引用類型數據在棧內存中保存的實際上是對象在堆內存中的引用地址。通過這個引用地址可以快速查找到保存中堆內存中的對象。

那么,在實際工作代碼開發中,有哪些方法去判斷一個數據是哪種數據類型呢?這就是本篇文章要重點介紹的內容——JavaScript中的數據類型判斷方法大全!

02
運算符typeof


typeof 運算符是 JavaScript 的基礎知識點,盡管它存在一定的局限性(見下文),但在前端js的實際編碼過程中,仍然是使用比較多的類型判斷方式。因此,掌握該運算符的特點,對于寫出好的代碼,就會起到很大的幫助作用。

typeof 運算符可能返回的類型字符串有:string, boolean, number, bigint, symbol, undefined, function, object。

// string
typeof '123'; // 'string'
typeof String(1); // 'string'

// boolean
typeof true; // 'boolean'
typeof Boolean(); // 'boolean'

// number
typeof 1; // number
typeof Number(10); // number
typeof NaN;//number

// undefined
typeof a; // undefined
typeof undefined; // undefined

// symbol
typeof Symbol(); // 'symbol'
typeof Symbol('foo'); // 'symbol'
typeof Symbol.iterator; // 'symbol'

// bigint
typeof 42n; // 'bigint'
typeof BigInt(1); // 'bigint'

// function
typeof function () { return 1 }; // function
typeof console.log; //function
typeof class cs {}; // 'function'
typeof String; // 'function'
typeof RegExp; // 'function'
typeof new Function(); // 'function'

// object
typeof null; // object
typeof []; // object
typeof [1,2,3]; // object
typeof {'id':11}; //object
typeof {}; //object
typeof Math; // 'object'
typeof new Number(1); // 'object'

需要注意的是typeof null返回為object,因為特殊值null被認為是一個空的對象引用。這是 JavaScript 語言的一個歷史遺留問題。在JavaScript 最初的版本中,使用 32 位的值表示一個變量,其中前 3 位用于表示值的類型。000 表示對象,010 表示浮點數,100 表示字符串,110 表示布爾值,和其他的值都被認為是指針。在這種表示法下,null 被解釋為一個全零的指針,也就是說它被認為是一個空對象引用,因此 typeof null的結果就是 "object"。

typeof 的局限性:在于無法精確判斷出 null、數組、對象、正則 的類型。引用類型,除了function返回function類型外,其它均返回object。所以如果要精準判斷,還需要使用其他技術手段,或組合判斷(見下文)。


03
屬性constructor


 在 JS 的原型鏈和原型對象中,會通過 new 一個構造函數,來創建實例對象。構造函數的原型對象上會有一個 constructor 屬性,指向了構造函數自身,所以實例對象通過原型鏈訪問 constructor 屬性,就能找到自己的構造函數,也就是自己的類型了。

new String('a').constructor === String; // true
"a".constructor === String; // true
(1).constructor === Number; // true
new Number(1).constructor === Number; // true
true.constructor === Boolean; // true
new Function().constructor === Function; // true
Symbol(0).constructor === Symbol; // true; // true
BigInt(1).constructor === BigInt; // true
new Error().constructor === Error; // true
[].constructor === Array; // true
new Date().constructor === Date; // true
new RegExp().constructor === RegExp; // true
new Object().constructor === Object; // true

注意:

  1. null 和 undefined 是無效的對象,因此是不會有 constructor 存在的,這兩種類型的數據需要通過其他方式來判斷。

  2. 函數的 constructor 不一定準確,這個主要體現在自定義對象上,當開發者重寫 prototype 后,原有的 constructor 引用會丟失,constructor 會默認為 Object。

String.prototype.constructor = function fn() {
    return {};
}
console.log("前端技術營".constructor)  // [Function: fn]
console.log("前端技術營".constructor === String) // false


04
instanceof


instanceof 運算符用于檢測構造函數的 prototype 屬性是否出現在某個實例對象的原型鏈上。也就是說檢測實例對象是不是屬于某個構造函數,可以用來做數據類型的檢測。不能檢測基本數據類型,只可用來判斷引用數據。

// 不能檢測基本數據類型
1 instanceof Number; // false
// 來檢測引用數據
[] instanceof Array; // true
[] instanceof Object; // true
new Object() instanceof Object; // true
new Date() instanceof Date; // true

function Person(){} 
new Person() instanceof Person; //true
Person instanceof Object; //true
new Date() instanceof Object; //true
new Person instanceof Object; // true

通過上面代碼可以看到,instanceof 既能夠判斷出 [ ] 是Array的實例,又能判斷出 [ ] 也是Object的實例,這是為什么呢?

通過《一文讓你搞懂javascript中的構造函數、實例、原型、原型鏈,和它們之間的關系》這篇文章就可以明白其原因了。instanceof 能夠判斷出 [ ].__proto__ 指向 Array.prototype,而 Array.prototype.__proto__ 又指向了Object.prototype,最終Object.prototype.__proto__ 指向了null,標志著原型鏈的結束。因此,[ ]、Array、Object 就在內部形成了一條原型鏈。


缺點:

  1. 不能檢測基本數據類型,只可用來判斷引用數據,obj instanceof Type右操作數必須是函數或者 class。

2. 原型鏈可能被修改,導致檢測結果不準確。


05
Object.prototype.toString


Object.prototype.toString——專業檢測數據類型一百年! 它是一個專門檢測數據類型的方法。

原理:當調用 Object.prototype.toString 時,JavaScript會將該調用傳遞給我們需要檢查類型的對象。因為Object.prototype.toString是一個函數,所以傳遞給它的唯一參數是this,而且該參數是一個隱式參數。具體如下:Object.prototype.toString.call(obj),由于toString是Object.prototype上的方法,因此我們傳遞給它的參數應該是一個對象,而Object.prototype.toString方法本身卻沒有傳遞參數。這就是為什么我們需要用call將它與需要檢查類型的對象連接起來。該方法可以指定函數內的this關鍵字上下文。因此,我們將檢查類型的對象作為首個參數傳遞給了toString方法,并使用call方法將Object.prototype.toString作為一個函數來執行。這樣JavaScript就會在上下文對象上執行Object.prototype.toString方法,從而返回一個表示該對象類型的字符串。

function checkDataType(data) {
    return Object.prototype.toString.call(data).slice(8, -1);
}

checkDataType(1); // Number
checkDataType('a'); // String
checkDataType(true); //Boolean
checkDataType(null); //Null
checkDataType(undefined); //Undefined
checkDataType(Symbol('b')); //Symbol
checkDataType(BigInt(10)); //BigInt
checkDataType([]); //Array
checkDataType({}); //Object
checkDataType(function fn() {}); //Function
checkDataType(new Date()); //Date
checkDataType(new RegExp()); //RegExp
checkDataType(new Error()); //Error
checkDataType(document); //HTMLDocument
checkDataType(window); //Window

編寫一個函數,對返回的字符串從第8位做一個截取,截取到倒數第一位,再去做類型比較。


06
Array.isArray專業檢測數組三十年


Array.isArray() 檢查傳遞的值是否為Array它不檢查值的原型鏈,也不依賴于它所附加的 Array 構造函數。對于使用數組字面量語法或 Array 構造函數創建的任何值,它都會返回 true

Array.isArray() 也拒絕原型鏈中帶有 Array.prototype,而實際不是數組的對象,但 instanceof Array 會接受。

// 下面的函數調用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
Array.isArray(new Array("a""b""c""d"));
Array.isArray(new Array(3));
// 鮮為人知的事實:其實 Array.prototype 也是一個數組:
Array.isArray(Array.prototype);

// 下面的函數調用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray("Array");
Array.isArray(true);
Array.isArray(false);
Array.isArray(new Uint8Array(32));
// 這不是一個數組,因為它不是使用數組字面量語法或 Array 構造函數創建的
Array.isArray({ __proto__: Array.prototype });

07
Number.isNaN專業檢測NaN三十年


JS 中有一個特殊的數字——NaN,表示 not a number,不是一個數字,但它卻歸屬于數字類型。上文中我們知道 typeof NaN 返回number。NaN 用于表示不是一個數字,它不等于任何值,包括它本身。ES6 提供了 Number.isNaN 方法,它能判斷一個值是否嚴格等于NaN。

Number.isNaN(NaN); //true
Number.isNaN(1); //false
Number.isNaN('abc'); //false;
Number.isNaN([]); //false;
Number.isNaN({}); //false


08
Symbol.toStringTag屬性


上面的 Object.prototype.toString 方法,之所以對不同的數據類型,返回不同的標識字符串,就是因為 Symbol.toStringTag 。Symbol.toStringTag 是一個內置符號屬性,它的值是一個字符串,用于表示一個對象的默認描述,也就是調用 Object.prototype.toString 會返回的內容。

const obj = {};
obj[Symbol.toStringTag] = 'ABCD';
console.log(Object.prototype.toString.call(obj))  // [object ABCD]

Symbol.toStringTag主要適用于需自定義類型的場景。


對于自定義對象,調用 Object.prototype.toString.call()方法,都只會返回 [object Object]。此時就可以使用 Symbol.toStringTag 來指定一個確定的類型了。

const arr = [];
Object.defineProperty(arr, Symbol.toStringTag, {
  value: 'MyArray'
})
console.log(Object.prototype.toString.call(arr))
// [object MyArray]


09
getPrototypeOf()


Object.getPrototypeOf() 靜態方法返回指定對象的原型,即內部 [[Prototype]] 屬性的值。

Object.getPrototypeOf([]) === Array.prototype; // true
Object.getPrototypeOf({}) === Object.prototype; // true
Object.getPrototypeOf(function fn(){}) === Function.prototype; // true
Object.getPrototypeOf(new Date()) === Date.prototype; // true
Object.getPrototypeOf(new RegExp()) === RegExp.prototype; // true
Object.getPrototypeOf(new Error()) === Error.prototype; // true


10
isPrototypeOf()


isPrototypeOf() 是 Object函數(類)的下的一個方法,用于判斷當前對象是否為另外一個對象的原型,如果是就返回 true,否則就返回 false。

let obj = new Object();
console.log(Object.prototype.isPrototypeOf(obj)); // true

obj對象是Object的實例,所以obj對象的原型(__proto__)指向Object的原型(prototype),上面會輸出true。


function Human() {}
let human = new Human();

console.log(Human.prototype.isPrototypeOf(human)); // true

因為human對象是Human的實例,所以human對象的原型(__proto__)指向Human的原型(prototype),上面會輸出true。


JavaScript中內置類Number、String、Boolean、Function、Array因為都是繼承Object,所以下面的輸出也都是true。

Object.prototype.isPrototypeOf(Number); // true
Object.prototype.isPrototypeOf(String); // true
Object.prototype.isPrototypeOf(Boolean); // true
Object.prototype.isPrototypeOf(Array); // true
Object.prototype.isPrototypeOf(Function); // true


另外值得一提的是 Function.prototype 也是Object的原型,因為Object也是一個函數(類),它們是互相生成的。

Object.prototype.isPrototypeOf(Function); // true
Function.prototype.isPrototypeOf(Object); // true


instanceof的區別:instanceof 作用的原理就是判斷實例的原型鏈中能否找到類的原型對象(prototype),而 isPrototypeOf 又是判斷類的原型對象(prototype)是否在實例的原型鏈上。這兩個表達的意思是一致的,之是寫法不同而已。

instanceof的寫法:A instanceof B,isPrototypeOf的寫法:B.prototype.isPrototypeOf(A)。


11
等值比較


直接通過與一個特定的值進行比較,從而判斷數據的類型。主要適用undefined、 window、 document、 null 等。

const value = null;
console.log(value === null) // true

// 同時判斷一個值是 undefined 或者 null
let value;
console.log(value == null) // true


如何判斷當前腳本運行在瀏覽器還是node環境中?

this === window ? 'browser' : 'node'

通過判斷Global對象是否為window,如果不為window,當前腳本沒有運行在瀏覽器中。

12
總結


本文整理總結了 JS 中常用的判斷數據類型的方法,判斷數據類型方法有很多,實際使用需要根據自己的需求使用最適合自己的方法。其中 typeof 和 Object.prototype.toString 使用場景是最多的,對一些特殊的數據類型,比如 null,NaN,自定義類型,可以選擇其它的方式去進行判斷,做到靈活運用。


該文章在 2024/4/19 18:05:26 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved