最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS必備技能之?dāng)?shù)據(jù)類型判斷與底層原理深入解析

 更新時間:2025年09月22日 08:31:20   作者:努力的小朱同學(xué)  
在JavaScript中類型判斷是指確定一個變量或值的類型的過程,這篇文章主要介紹了JS必備技能之?dāng)?shù)據(jù)類型判斷與底層原理的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、簡介

? 精準(zhǔn)判斷數(shù)據(jù)類型是每一位前端開發(fā)者的必備技能,但 JS 因存在基礎(chǔ)類型與引用類型的區(qū)分以及歷史遺留問題等,單一判斷方式往往無法覆蓋所有場景。本文梳理并解析了 5 類常用的數(shù)據(jù)類型判斷方法,包括:基礎(chǔ)類型常用的 typeof、對象類型專屬的 instanceof 、全類型通用的 Object.prototype.toString.call()、基于構(gòu)造函數(shù)引用的 constructor,以及針對數(shù)組、NaN、整數(shù)等場景的特定判斷方案。

基礎(chǔ)類型:

String、Number、Boolean、Null、Undefined、Symbol、bigint(ES2020新增)。

這些類型的數(shù)據(jù)占據(jù)的空間較小且大小是固定的,因此數(shù)據(jù)直接存儲在棧(stack)內(nèi)存中,方便頻繁調(diào)用數(shù)據(jù)。

引用類型:

? Object(包含Array、Function、Date、RegExp、Map、Set等等)。

? 該類型的數(shù)據(jù)占據(jù)的空間較大且大小不固定,是將數(shù)據(jù)存儲在堆(heap)內(nèi)存中,并在棧(stack)內(nèi)存中存儲一個引用指針,該指針指向當(dāng)前數(shù)據(jù)在堆中的實際空間地址。

二、具體方案

1、typeof

? typeof 運(yùn)算符常用于獲取基礎(chǔ)數(shù)據(jù)的類型,可以獲取到一個表示數(shù)據(jù)的類型的字符串,類型字符串有:number、string、boolean、object、function、undefined、symbol、bigint。

? typeof 運(yùn)算符在遇到除 null 之外基礎(chǔ)類型的數(shù)據(jù),都能正常獲取其類型字符串(number、string等),而遇到 null 會返回 object ,這是由于歷史遺留問題。但遇到對象類型數(shù)據(jù),其判斷結(jié)果具有局限性,遇到函數(shù)則會返回 function ,而遇到其他對象(如對象、數(shù)組、日期等)都只會返回 object,因此無法區(qū)分具體對象類型。

基本語法:

typeof 數(shù)據(jù)

判斷原理:

? JS中的數(shù)據(jù),在底層中都是以二進(jìn)制的形式存儲的,并且會通過低位的 “類型標(biāo)簽”(tag) 來區(qū)分不同數(shù)據(jù)類型,不同的JS引擎具體實現(xiàn)不同,比如V8引擎中:二進(jìn)制000結(jié)尾-表示對象類型、二進(jìn)制1結(jié)尾-表示整數(shù)類型等等。typeof 的原理就是通過底層標(biāo)簽來判斷數(shù)據(jù)的類型,而特殊的null,其所有二進(jìn)制位都是 0 ,所以引擎會將以 000 結(jié)尾的標(biāo)簽將其誤判為 object。

使用示例:

// 數(shù)字類型
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 盡管NaN是非數(shù)字的意思
typeof Number(1) === 'number'; // 但不建議使用!

// bigInt
typeof 42n === 'bigint'; 

// 字符串類型
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof返回的是字符串
typeof String("abc") === 'string'; // 但不建議使用!

// 布爾類型
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 但不建議使用!

// Symbol類型
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';

// Undefined
typeof undefined === 'undefined';
var a // 聲明但未賦值
typeof a === 'undefined';
typeof b === 'undefined'; // 未聲明未賦值

// 對象類型
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object'; // 數(shù)組會被判斷為對象
typeof new Date() === 'object';
typeof null === 'object'; // null 也會被判斷為對象

// 函數(shù)
typeof function(){} === 'function';
typeof Math.sin === 'function';

2、instanceof

? instanceof 運(yùn)算符常用于判斷對象數(shù)據(jù)的具體數(shù)據(jù)類型,可以判斷一個對象數(shù)據(jù)是否為某個構(gòu)造函數(shù)的實例,返回一個布爾值。

? instanceof 運(yùn)算符不適用于基礎(chǔ)數(shù)據(jù)類型(包括null),但適用于基礎(chǔ)類型的包裝對象。并且如果判斷數(shù)組、函數(shù)等具體對象數(shù)據(jù)是否為 Object 類型,結(jié)果也會是true,因為 Object 類型屬于最外層的大類型。因此想要判斷具體的對象類型,需要精準(zhǔn)的判斷,不能用排除法。

? 由于原型鏈?zhǔn)强梢员恍薷牡?,因此判斷結(jié)果并非絕對可靠。

基本語法:

對象 instanceof 構(gòu)造函數(shù)

判斷原理:

? JS中對象數(shù)據(jù)存在原型鏈,instanceof 就是通過沿著左邊對象的原型鏈向上查找,如果在左邊對象的原型鏈上存在右邊構(gòu)造函數(shù)的 prototype ,則說明左邊對象是右邊構(gòu)造函數(shù)的實例,也就是說左邊對象屬于右邊構(gòu)造函數(shù)的類型,返回 true,否則返回 false。

? 因此該方案只適用于同一個全局環(huán)境下的判斷,因為在不同的全局環(huán)境(如iframe)中,構(gòu)造函數(shù)的 prototype 指向的是不同的對象,會導(dǎo)致判斷錯誤。

使用示例:

// 數(shù)組
var a = [1,2,3]
console.log(a instanceof Array)  // true
console.log(a instanceof Object) // true,兩者都成立
var a2 = new Array
console.log(a2 instanceof Array)  // true
console.log(a2 instanceof Object) // true

// 函數(shù)(包括箭頭函數(shù))
var b = function() {}
console.log(b instanceof Function) // true
console.log((()=>{}) instanceof Function) // true 
console.log(b instanceof Object)  // true

// 對象
var c = {}
console.log(c instanceof Object) // true
console.log(Date instanceof Object) // true

// 內(nèi)置對象
var str = new String()
str instanceof String // true
var myDate = new Date()
myDate instanceof Date;     // true
myDate instanceof Object;   // true

// 基礎(chǔ)數(shù)據(jù)的包裝類
const numObj = new Number(123);
numObj instanceof Number; // true(包裝對象可被判斷)
123 instanceof Number; // false(原始值不可被判斷)

3、Object.prototype.toString.call()

? Object.prototype.toString.call() 方法可用于判斷所有數(shù)據(jù)的具體類型,可以獲取到一個表示數(shù)據(jù)具體類型的標(biāo)準(zhǔn)字符串,返回格式為: [object Xxxx],其中 Xxxx 就是數(shù)據(jù)的具體類型,無論是基本數(shù)據(jù)類型還是對象數(shù)據(jù)類型,都能精準(zhǔn)的區(qū)分。

基本語法:

Object.prototype.toString.call(數(shù)據(jù));

判斷原理:

? 每個JS內(nèi)置對象都有一個內(nèi)部屬性 [[Class]](抽象概念,無法直接訪問),其值為該對象的類型標(biāo)識(如 Array、Date、Number、String 等)。當(dāng)調(diào)用 Object 原型上的 toString() 方法,并通過 call() 方法改變this的指向到目標(biāo)數(shù)據(jù)時,對于對象類型數(shù)據(jù),該方法會直接讀取目標(biāo)數(shù)據(jù)的 [[Class]] 屬性,并返回對應(yīng)類型字符串 [object [[Class]]];對于基本類型數(shù)據(jù), call() 方法會先自動將其轉(zhuǎn)換為對應(yīng)的包裝對象,再讀取其 [[Class]] 屬性,最后返回對應(yīng)類型字符串 [object [[Class]]]。

使用示例:

Object.prototype.toString.call(123);         // "[object Number]"
Object.prototype.toString.call('abc');       // "[object String]"
Object.prototype.toString.call(true);        // "[object Boolean]"
Object.prototype.toString.call(null);        // "[object Null]"
Object.prototype.toString.call(undefined);   // "[object Undefined]"
Object.prototype.toString.call([1, 2]);      // "[object Array]"
Object.prototype.toString.call(new Date());  // "[object Date]"
Object.prototype.toString.call(/abc/);       // "[object RegExp]"
Object.prototype.toString.call(function(){}); // "[object Function]"
Object.prototype.toString.call({});          // "[object Object]"
Object.prototype.toString.call(Symbol());    // "[object Symbol]"
Object.prototype.toString.call(123n); // "[object BigInt]"
Object.prototype.toString.call(new Map()); // "[object Map]"
Object.prototype.toString.call(new Set()); // "[object Set]"
Object.prototype.toString.call(new WeakMap()); // "[object WeakMap]"

4、constructor

? constructor 常用于判斷對象的具體類型,其是對象的一個屬性,它指向創(chuàng)建該對象的構(gòu)造函數(shù),通過與特定的構(gòu)造函數(shù)進(jìn)行比較,區(qū)分對象的具體類型。

? 對于除 null、undefined 之外基礎(chǔ)類型數(shù)據(jù),在其調(diào)用 constructor 屬性時,JS會自動進(jìn)行“裝箱”操作,將其臨時變?yōu)閷?yīng)的包裝對象,從而擁有 constructor 屬性;對于null、undefined,它們沒有對應(yīng)的包裝對象,因此無法調(diào)用 constructor。

? 由于 constructor 屬性是可以被修改的,因此判斷結(jié)果并非絕對可靠。

基本語法:

數(shù)據(jù).constructor === 構(gòu)造函數(shù)

判斷原理:

? JS中每個對象在創(chuàng)建時都會關(guān)聯(lián)一個構(gòu)造函數(shù),constructor 屬性就是對這個構(gòu)造函數(shù)的引用。例如,數(shù)組是由 Array 構(gòu)造函數(shù)創(chuàng)建的,所以數(shù)組的 constructor 屬性指向 Array;日期對象由 Date 構(gòu)造函數(shù)創(chuàng)建,其 constructor 屬性指向 Date。因此,通過比較對象的 constructor 與對應(yīng)的構(gòu)造函數(shù),就能判斷出對象的具體類型。

使用示例:
// 基礎(chǔ)數(shù)據(jù)類型(除 null、undefined 外,通過包裝對象實現(xiàn))
(123).constructor === Number; // true
// 等價于
Number(123).constructor === Number;

'abc'.constructor === String; // true
// 等價于
String('abc').constructor === String;

true.constructor === Boolean; // true
// 等價于

// 引用數(shù)據(jù)類型
[1, 2].constructor === Array; // true(可識別數(shù)組)
new Date().constructor === Date; // true(可識別日期對象)
({}).constructor === Object; // true

5、特定類型判斷

① Array.isArray()

? 判斷數(shù)據(jù)是否為數(shù)組類型。

var arr = []
Array.isArray(arr); // true

② ===

? 準(zhǔn)確判斷 null 和 undefined。

let a = null;
a === null; // true

let b = undefined;
b === undefined; // true

a === b; // false

③ Number.isNaN()

? 判斷數(shù)據(jù)是否為NaN。該方法不會將參數(shù)強(qiáng)制轉(zhuǎn)換為數(shù)字類型,會直接判斷傳入的參數(shù)是否是 NaN,而全局的 isNaN() 方法會強(qiáng)制轉(zhuǎn)換參數(shù)為數(shù)字,導(dǎo)致非NaN值被誤判,因此更推薦使用 Number.isNaN()。

let n = NaN;
Number.isNaN(n); // true

④ Number.isInteger()

? 判斷數(shù)據(jù)是否為整數(shù)。

Number.isInteger(1); // true
Number.isInteger(1.2); // false
Number.isInteger(1.00); // true

三、 總結(jié)

? 沒有萬能的方法,只有最適合當(dāng)前場景的方法。

判斷方法適用場景關(guān)鍵局限精準(zhǔn)度
typeof基礎(chǔ)類型(除 null)、函數(shù)快速判斷null 誤判為 object,無法區(qū)分?jǐn)?shù)組 / 日期等對象基礎(chǔ)類型高,引用類型低
instanceof引用類型(數(shù)組、日期等)的實例判斷不支持原始基礎(chǔ)類型,原型鏈修改會導(dǎo)致誤判引用類型較高(需注意全局環(huán)境)
Object.prototype.toString.call()所有類型(基礎(chǔ) + 引用)精準(zhǔn)判斷語法相對繁瑣,需處理返回的標(biāo)準(zhǔn)格式字符串最高(全場景通用)
constructor基礎(chǔ)類型(除 null/undefined)、引用類型判斷constructor 可被修改,null/undefined 無該屬性較高(需警惕屬性篡改)
特定判斷單一類型(數(shù)組、NaN、整數(shù)等)精準(zhǔn)校驗適用范圍窄,僅針對特定場景極高(場景專屬)

總結(jié)

到此這篇關(guān)于JS必備技能之?dāng)?shù)據(jù)類型判斷與底層原理的文章就介紹到這了,更多相關(guān)JS數(shù)據(jù)類型判斷與底層原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript實現(xiàn)的購物車效果可以運(yùn)用在好多地方

    JavaScript實現(xiàn)的購物車效果可以運(yùn)用在好多地方

    JavaScript實現(xiàn)的購物車效果,當(dāng)然這個效果可以運(yùn)用在好多地方,比如好友的選擇,人力資源模塊等等,需要的朋友可以參考下
    2014-05-05
  • JavaScript?的setTimeout與事件循環(huán)機(jī)制event-loop

    JavaScript?的setTimeout與事件循環(huán)機(jī)制event-loop

    這篇文章主要介紹了JavaScript?的setTimeout與事件循環(huán)機(jī)制event-loop,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • js原生實現(xiàn)移動端手指滑動輪播圖效果的示例

    js原生實現(xiàn)移動端手指滑動輪播圖效果的示例

    下面小編就為大家分享一篇js原生實現(xiàn)移動端手指滑動輪播圖效果的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • JS中的模糊查詢功能

    JS中的模糊查詢功能

    這篇文章主要介紹了JS中的模糊查詢功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • js解決url傳遞中文參數(shù)亂碼問題的方法詳解

    js解決url傳遞中文參數(shù)亂碼問題的方法詳解

    前后臺用js傳參過程中,如果是中文就容易出現(xiàn)亂碼,下面這篇文章主要給大家介紹了關(guān)于js解決url傳遞中文參數(shù)亂碼問題的的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 理解JavaScript中的對象 推薦

    理解JavaScript中的對象 推薦

    JavaScript有一種object數(shù)據(jù)類型,但是這種對象不同于c#或vb中的對象,在c#中,我們通過類創(chuàng)建一個對象,一個類相當(dāng)于創(chuàng)建對象的模板,定義了對象的屬性和方法,這些對象和方法將永遠(yuǎn)固定,我們不能在運(yùn)行時不能增加對象的屬性和方法。
    2011-01-01
  • javascript 層隱藏和顯示的代碼

    javascript 層隱藏和顯示的代碼

    javascript 層隱藏和顯示的代碼
    2009-07-07
  • D3.js中data(), enter() 和 exit()的問題詳解

    D3.js中data(), enter() 和 exit()的問題詳解

    相信大多數(shù)人對D3.js并不陌生。這是一個由紐約時報可視化編輯 Mike Bostock與他斯坦福的教授和同學(xué)合作開發(fā)的數(shù)據(jù)文件處理的JavaScript Library,全稱叫做Data-Driven Documents,在d3.js中data(), enter() 和 exit()比較常見,下面給大家就這方面的知識給大家詳解
    2015-08-08
  • js實現(xiàn)簡單商品篩選功能

    js實現(xiàn)簡單商品篩選功能

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)商品篩選功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • layui使用技巧和常見問題匯總

    layui使用技巧和常見問題匯總

    layui技巧:下拉框未展示問題;下拉框的onchange事件處理;關(guān)閉彈出層,重新加載父頁面;父頁面如何傳遞參數(shù)給彈出層的iframe頁面;表單元素處于禁用狀態(tài);表單提交如何獲取表單元素值集合;數(shù)據(jù)表格固定列;帶搜索的下拉框;表單提交阻止頁面跳轉(zhuǎn);父頁面和子窗口傳遞值
    2024-07-07

最新評論

乌拉特中旗| 安化县| 乌海市| 罗城| 沁源县| 冕宁县| 上虞市| 晋中市| 衡山县| 商洛市| 寻甸| 黑河市| 成安县| 额尔古纳市| 托里县| 工布江达县| 福建省| 全椒县| 来宾市| 三门峡市| 芒康县| 山东省| 满洲里市| 浙江省| 鲜城| 靖西县| 开化县| 滨海县| 怀柔区| 咸宁市| 平凉市| 宜都市| 平凉市| 宁安市| 武定县| 开化县| 绍兴县| 花垣县| 格尔木市| 潞城市| 连江县|