JavaScript基本類型與引用類型區(qū)別解析
更新時間:2025年11月17日 14:34:21 作者:指尖跳動的光
文章介紹了JavaScript中基本類型和引用類型的區(qū)別,包括它們的存儲位置、賦值行為、比較方式、可變性、類型數(shù)量、方法支持等特性,同時,還討論了基本類型和引用類型在函數(shù)參數(shù)傳遞、深拷貝與淺拷貝、性能優(yōu)化以及檢測方法等方面的區(qū)別和注意事項,感興趣的朋友一起看看吧
1. 基本類型(Primitive Types)
1.1 特點
- 按值訪問:直接存儲在棧內存中,變量保存的是數(shù)據(jù)的實際值。
- 不可變:修改基本類型的值會創(chuàng)建一個新值,原值不會被改變。
- 類型固定:JavaScript 的基本類型共有 7 種:
- number(數(shù)字)
- string(字符串)
- boolean(布爾值)
- null(空值)
- undefined(未定義)
- symbol(ES6 新增,唯一標識符)
- bigint(ES2020 新增,大整數(shù))
1.2 示例
let a = 10; let b = a; // 賦值時復制實際值 b = 20; // 修改 b 不影響 a console.log(a); // 10 console.log(b); // 20
1.3 關鍵行為
- 賦值:復制實際值,兩個變量獨立。
- 比較:比較的是值是否相等。
let x = "hello"; let y = "hello"; console.log(x === y); // true(值相同)
- 方法調用:字符串、數(shù)字等基本類型調用方法時,會臨時轉換為對象(如 “abc”.toUpperCase()),但原值不變。
- 字符串調用方法
let str = "hello"; console.log(str.length); // 5 console.log(str.toUpperCase()); // "HELLO"
- str 是一個基本類型的字符串,但可以調用 length 屬性和 toUpperCase() 方法。
- 引擎內部會臨時將 str 轉換為 new String(“hello”) 對象,調用方法后,臨時對象被丟棄。
- 數(shù)字調用方法
let num = 3.14; console.log(num.toFixed(2)); // "3.14"
- num 是基本類型的數(shù)字,但可以調用 toFixed() 方法。
- 引擎臨時將其轉換為 new Number(3.14) 對象,調用方法后銷毀。
- 布爾值調用方法
let bool = true; console.log(bool.toString()); // "true"
- bool 是基本類型的布爾值,但可以調用 toString() 方法。
- 引擎臨時將其轉換為 new Boolean(true) 對象,調用方法后銷毀。
- 字符串調用方法
2. 引用類型(Reference Types)
2.1 特點
- 按引用訪問:存儲在堆內存中,變量保存的是數(shù)據(jù)的內存地址(引用)。
- 可變:修改引用類型的屬性會直接影響原對象。
- 類型動態(tài):包括所有對象類型:
- Object(普通對象)
- Array(數(shù)組)
- Function(函數(shù))
- Date(日期)
- RegExp(正則表達式)
- Map、Set 等(ES6 新增)
2.2 示例
let obj1 = { name: "Alice" };
let obj2 = obj1; // 賦值時復制引用(地址)
obj2.name = "Bob"; // 修改 obj2 會影響 obj1
console.log(obj1.name); // "Bob"
console.log(obj2.name); // "Bob"
2.3 關鍵行為
- 賦值:復制引用(地址),兩個變量指向同一對象。
- 比較:比較的是引用地址是否相同(即使內容相同,地址不同也返回 false)。
let arr1 = [1, 2]; let arr2 = [1, 2]; console.log(arr1 === arr2); // false(地址不同) console.log(arr1 === arr1); // true(同一對象)
- 方法調用:直接修改原對象(如 arr.push(3) 會改變原數(shù)組)。
3. 核心區(qū)別總結
| 特性 | 基本類型 | 引用類型 |
|---|---|---|
| 存儲位置 | 棧內存(直接存儲值) | 堆內存(存儲地址,變量保存引用) |
| 賦值行為 | 復制實際值(獨立) | 復制引用(共享同一對象) |
| 比較方式 | 比較值是否相等 | 比較引用地址是否相同 |
| 可變性 | 不可變(修改創(chuàng)建新值) | 可變(直接修改原對象) |
| 類型數(shù)量 | 固定 7 種 | 動態(tài)(所有對象類型) |
| 方法支持 | 臨時轉換為對象調用方法(原值不變) | 直接調用方法修改原對象 |
4. 常見場景與注意事項
4.1 函數(shù)參數(shù)傳遞
- 基本類型:函數(shù)內修改參數(shù)不影響外部變量。
function changeValue(num) { num = 100; } let a = 10; changeValue(a); console.log(a); // 10(未改變) - 引用類型:函數(shù)內修改對象屬性會影響外部變量。
function changeObj(obj) { obj.name = "Bob"; } let person = { name: "Alice" }; changeObj(person); console.log(person.name); // "Bob"(被修改)
4.2 深拷貝 vs 淺拷貝
- 淺拷貝:僅復制引用(如 let arr2 = arr1),修改嵌套對象會互相影響。
- 深拷貝:完全復制對象(如使用 JSON.parse(JSON.stringify(obj)) 或工具庫如 Lodash 的 _.cloneDeep)。
4.3 性能優(yōu)化
- 基本類型(如頻繁操作的數(shù)字、字符串)適合存儲在棧中,訪問速度快。
- 引用類型(如大型對象、數(shù)組)適合堆存儲,但需注意避免意外共享引用。
5. 檢測方法
5.1 基本數(shù)據(jù)類型-》檢測類型
- typeof 運算符
- 適用于大多數(shù)基本類型,但 null 會返回 “object”(歷史遺留問題)。
typeof "hello"; // "string" typeof 42; // "number" typeof true; // "boolean" typeof undefined; // "undefined" typeof Symbol("foo"); // "symbol" typeof 10n; // "bigint" typeof null; // "object" ?? 特殊情況
- 適用于大多數(shù)基本類型,但 null 會返回 “object”(歷史遺留問題)。
- 嚴格等于 === 檢測 null 和 undefined
let x = null; let y = undefined; console.log(x === null); // true console.log(y === undefined); // true
- Object.prototype.toString.call()(最準確)
Object.prototype.toString.call("hello"); // "[object String]" Object.prototype.toString.call(42); // "[object Number]" 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(Symbol("foo")); // "[object Symbol]" Object.prototype.toString.call(10n); // "[object BigInt]"
5.2 引用數(shù)據(jù)類型-》檢測類型
- typeof 運算符
- typeof 對引用類型通常返回 “object”(除了 function):
typeof {}; // "object" typeof []; // "object" typeof function() {}; // "function" ?? 特殊情況 typeof new Date(); // "object" typeof /regex/; // "object"
- typeof 對引用類型通常返回 “object”(除了 function):
- instanceof 運算符
- 檢測對象是否是某個構造函數(shù)的實例:
[] instanceof Array; // true {} instanceof Object; // true function() {} instanceof Function; // true new Date() instanceof Date; // true - 局限性:
- 不能檢測基本類型(如 “str” instanceof String 返回 false)。
- 跨框架(iframe)時可能不準確(不同全局對象的構造函數(shù)不同)。
- 檢測對象是否是某個構造函數(shù)的實例:
- constructor 屬性
- 返回對象的構造函數(shù):
"hello".constructor === String; // true (42).constructor === Number; // true [].constructor === Array; // true ({}).constructor === Object; // true - 局限性:
- 如果對象是 null 或 undefined,會報錯(Cannot read property ‘constructor’ of null)。
- 可以被手動修改(obj.constructor = Foo),不可靠。
- 返回對象的構造函數(shù):
- Object.prototype.toString.call()(最準確)
Object.prototype.toString.call([]); // "[object Array]" Object.prototype.toString.call({}); // "[object Object]" Object.prototype.toString.call(function() {}); // "[object Function]" Object.prototype.toString.call(new Date()); // "[object Date]" Object.prototype.toString.call(/regex/); // "[object RegExp]"
5.3 綜合檢測方法
- 判斷是否為基本類型
function isPrimitive(value) { return ( value === null || value === undefined || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol" || typeof value === "bigint" ); } - 判斷具體類型(推薦 Object.prototype.toString)
function getType(value) { return Object.prototype.toString.call(value).slice(8, -1).toLowerCase(); } getType("hello"); // "string" getType(42); // "number" getType([]); // "array" getType({}); // "object" getType(null); // "null" getType(undefined); // "undefined" getType(function() {}); // "function" getType(new Date()); // "date" - 判斷是否為數(shù)組
Array.isArray([]); // true [] instanceof Array; // true Object.prototype.toString.call([]) === "[object Array]"; // true
- 判斷是否為 null 或 undefined
function isNullOrUndefined(value) { return value === null || value === undefined; }
5.4 檢測類型總結
| 檢測方式 | 基本類型 | 引用類型 | 特殊情況 |
|---|---|---|---|
| typeof | ?(除 null) | ??(function 除外) | null 返回 “object” |
| instanceof | ? | ? | 跨框架不準確 |
| constructor | ?(除 new String() 等) | ? | 可被修改,null/undefined 報錯 |
| Object.prototype.toString.call() | ? | ? | 最準確 |
- 推薦做法
- 基本類型:優(yōu)先用 typeof + 特殊處理 null。
- 引用類型:用 Object.prototype.toString.call() 或 Array.isArray() 等特定方法。
- 避免 instanceof 和 constructor,除非明確知道它們的局限性。
到此這篇關于JavaScript基本類型與引用類型有什么區(qū)別的文章就介紹到這了,更多相關js 基本類型與引用類型區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JS實現(xiàn)點擊下拉菜單把選擇的內容同步到input輸入框內的實例
下面小編就為大家分享一篇JS實現(xiàn)點擊下拉菜單把選擇的內容同步到input輸入框內的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
Electron內嵌網(wǎng)頁實現(xiàn)打印預覽功能的示例代碼
這篇文章主要介紹了Electron內嵌網(wǎng)頁實現(xiàn)打印預覽功能的方式,文章通過代碼示例給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2025-06-06
調試Javascript代碼(瀏覽器F12及VS中debugger關鍵字)
目前,常用的瀏覽器IE、Chrome、Firefox都有相應的腳本調試功能下面我就介紹如何在瀏覽器/VS中調試我們的JS代碼,感興趣的你可不要走開啊,希望本文對你有所幫助2013-01-01
javascript中break,continue和return語句用法小結
break,continue和return這三個語句的用法新手們經(jīng)常弄混淆,至少在我學習c語言的時候經(jīng)常把它們的用法給搞錯。不過現(xiàn)在好了,我已徹底搞清楚它們之間的用法2012-05-05

