LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

厲害了!這是JavaScript中的數(shù)據(jù)類型判斷方法最全總結(jié)

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


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

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

那么,在實(shí)際工作代碼開發(fā)中,有哪些方法去判斷一個(gè)數(shù)據(jù)是哪種數(shù)據(jù)類型呢?這就是本篇文章要重點(diǎn)介紹的內(nèi)容——JavaScript中的數(shù)據(jù)類型判斷方法大全!

02
運(yùn)算符typeof


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

typeof 運(yùn)算符可能返回的類型字符串有: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,因?yàn)樘厥庵祅ull被認(rèn)為是一個(gè)空的對象引用。這是 JavaScript 語言的一個(gè)歷史遺留問題。在JavaScript 最初的版本中,使用 32 位的值表示一個(gè)變量,其中前 3 位用于表示值的類型。000 表示對象,010 表示浮點(diǎn)數(shù),100 表示字符串,110 表示布爾值,和其他的值都被認(rèn)為是指針。在這種表示法下,null 被解釋為一個(gè)全零的指針,也就是說它被認(rèn)為是一個(gè)空對象引用,因此 typeof null的結(jié)果就是 "object"。

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


03
屬性constructor


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

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 存在的,這兩種類型的數(shù)據(jù)需要通過其他方式來判斷。

  2. 函數(shù)的 constructor 不一定準(zhǔn)確,這個(gè)主要體現(xiàn)在自定義對象上,當(dāng)開發(fā)者重寫 prototype 后,原有的 constructor 引用會丟失,constructor 會默認(rèn)為 Object。

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


04
instanceof


instanceof 運(yùn)算符用于檢測構(gòu)造函數(shù)的 prototype 屬性是否出現(xiàn)在某個(gè)實(shí)例對象的原型鏈上。也就是說檢測實(shí)例對象是不是屬于某個(gè)構(gòu)造函數(shù),可以用來做數(shù)據(jù)類型的檢測。不能檢測基本數(shù)據(jù)類型,只可用來判斷引用數(shù)據(jù)。

// 不能檢測基本數(shù)據(jù)類型
1 instanceof Number; // false
// 來檢測引用數(shù)據(jù)
[] 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的實(shí)例,又能判斷出 [ ] 也是Object的實(shí)例,這是為什么呢?

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


缺點(diǎn):

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

2. 原型鏈可能被修改,導(dǎo)致檢測結(jié)果不準(zhǔn)確。


05
Object.prototype.toString


Object.prototype.toString——專業(yè)檢測數(shù)據(jù)類型一百年! 它是一個(gè)專門檢測數(shù)據(jù)類型的方法。

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

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

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


06
Array.isArray專業(yè)檢測數(shù)組三十年


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

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

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

// 下面的函數(shù)調(diào)用都返回 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));
// 這不是一個(gè)數(shù)組,因?yàn)樗皇鞘褂脭?shù)組字面量語法或 Array 構(gòu)造函數(shù)創(chuàng)建的
Array.isArray({ __proto__: Array.prototype });

07
Number.isNaN專業(yè)檢測NaN三十年


JS 中有一個(gè)特殊的數(shù)字——NaN,表示 not a number,不是一個(gè)數(shù)字,但它卻歸屬于數(shù)字類型。上文中我們知道 typeof NaN 返回number。NaN 用于表示不是一個(gè)數(shù)字,它不等于任何值,包括它本身。ES6 提供了 Number.isNaN 方法,它能判斷一個(gè)值是否嚴(yán)格等于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 方法,之所以對不同的數(shù)據(jù)類型,返回不同的標(biāo)識字符串,就是因?yàn)?nbsp;Symbol.toStringTag 。Symbol.toStringTag 是一個(gè)內(nèi)置符號屬性,它的值是一個(gè)字符串,用于表示一個(gè)對象的默認(rèn)描述,也就是調(diào)用 Object.prototype.toString 會返回的內(nèi)容。

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

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


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

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


09
getPrototypeOf()


Object.getPrototypeOf() 靜態(tài)方法返回指定對象的原型,即內(nèi)部 [[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函數(shù)(類)的下的一個(gè)方法,用于判斷當(dāng)前對象是否為另外一個(gè)對象的原型,如果是就返回 true,否則就返回 false。

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

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


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

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

因?yàn)閔uman對象是Human的實(shí)例,所以human對象的原型(__proto__)指向Human的原型(prototype),上面會輸出true。


JavaScript中內(nèi)置類Number、String、Boolean、Function、Array因?yàn)槎际抢^承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的原型,因?yàn)镺bject也是一個(gè)函數(shù)(類),它們是互相生成的。

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


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

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


11
等值比較


直接通過與一個(gè)特定的值進(jìn)行比較,從而判斷數(shù)據(jù)的類型。主要適用undefined、 window、 document、 null 等。

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

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


如何判斷當(dāng)前腳本運(yùn)行在瀏覽器還是node環(huán)境中?

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

通過判斷Global對象是否為window,如果不為window,當(dāng)前腳本沒有運(yùn)行在瀏覽器中。

12
總結(jié)


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


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

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲乱码一区二区 | 中文字幕欧美精品制服丝袜 | 一级a做片免费观看久久 | 亚洲人AV在线不卡 | 在线观看最新中文字幕AV | 亚洲成成熟女人专区 |