目錄
Symbol類型
一、Symbol 的核心特性
1.?唯一性
2.?不可變性
3.?不可枚舉性
二、創建 Symbol
1.?基礎創建
2.?全局 Symbol 注冊表
三、Symbol 作為對象屬性
1.?定義 Symbol 屬性
2.?遍歷 Symbol 屬性
四、內置 Symbol 值
五、實際應用場景
1.?避免屬性名沖突
2.?模擬私有屬性
3.?定義迭代器
六、注意事項
七、總結
BigInt類型
一、BigInt 的核心特性
1.?定義與語法
2.?類型檢測
3.?數值范圍
二、BigInt 的運算規則
1.?算術運算
2.?比較運算
3.?位運算
4.?禁止混合運算
三、BigInt 的創建與轉換
1.?類型轉換
2.?類型強制轉換
四、BigInt 的應用場景
1.?高精度整數計算
2.?時間戳與唯一ID
3.?數學庫與算法
五、注意事項與兼容性
1.?兼容性
2.?JSON 序列化
3.?Math 對象方法
4.?性能考量
六、示例代碼
1.?大數計算
2.?類型檢測與轉換
七、總結
Symbol類型
Symbol?是 ES6 引入的一種?原始數據類型,用于創建?唯一且不可變?的標識符,常用于對象屬性的鍵,避免命名沖突。
一、Symbol 的核心特性
1.?唯一性
每個 Symbol 值都是唯一的,即使描述符(description
)相同:
const sym1 = Symbol('key');
const sym2 = Symbol('key');
console.log(sym1 === sym2); // false
2.?不可變性
Symbol 值一旦創建,無法被修改,也無法通過?new
?創建(避免裝箱為對象):
const sym = Symbol();
// const obj = new Symbol(); // ? 報錯:Symbol is not a constructor
3.?不可枚舉性
作為對象屬性時,Symbol 鍵默認不會被常規方法遍歷:
const obj = { [Symbol('key')]: 'value' };
console.log(Object.keys(obj)); // []
console.log(Reflect.ownKeys(obj)); // [Symbol(key)](包含 Symbol 鍵)
二、創建 Symbol
1.?基礎創建
// 無描述符
const sym1 = Symbol();// 帶描述符(用于調試)
const sym2 = Symbol('description');
console.log(sym2.description); // "description"
2.?全局 Symbol 注冊表
通過?Symbol.for()
?創建或獲取全局共享的 Symbol:
const globalSym1 = Symbol.for('globalKey'); // 創建或獲取
const globalSym2 = Symbol.for('globalKey');
console.log(globalSym1 === globalSym2); // true// 獲取全局 Symbol 的鍵
console.log(Symbol.keyFor(globalSym1)); // "globalKey"
-
全局注冊表機制:根據?
key
?在全局注冊表中查找或創建 Symbol。 -
相同?
key
?返回同一 Symbol。
三、Symbol 作為對象屬性
1.?定義 Symbol 屬性
const id = Symbol('id');
const user = {name: 'Alice',[id]: 123 // Symbol 鍵
};console.log(user[id]); // 123
2.?遍歷 Symbol 屬性
需使用?Object.getOwnPropertySymbols()
:
const symbols = Object.getOwnPropertySymbols(user); // [Symbol(id)]
四、內置 Symbol 值
JavaScript 預定義了一系列?內置 Symbol,用于改變對象的默認行為:
內置 Symbol | 用途 | 示例 |
---|---|---|
Symbol.iterator | 定義對象的默認迭代器 | obj[Symbol.iterator] = function*() { yield 1; } |
Symbol.toStringTag | 定制?Object.prototype.toString ?輸出 | obj[Symbol.toStringTag] = 'MyObject'; ?→?obj.toString() ?→?[object MyObject] |
Symbol.hasInstance | 自定義?instanceof ?行為 | class MyClass { static [Symbol.hasInstance](obj) { ... } } |
Symbol.species | 指定派生對象的構造函數 | class MyArray extends Array { static get [Symbol.species]() { return Array; } } |
五、實際應用場景
1.?避免屬性名沖突
// 庫 A 的擴展
const LIB_A_KEY = Symbol('libA');
Object.prototype[LIB_A_KEY] = function() { /* ... */ };// 庫 B 的擴展
const LIB_B_KEY = Symbol('libB');
Object.prototype[LIB_B_KEY] = function() { /* ... */ };
2.?模擬私有屬性
const _counter = Symbol('counter');
class Counter {constructor() {this[_counter] = 0; // “私有”屬性}increment() {this[_counter]++;}
}
3.?定義迭代器
const range = {start: 1,end: 5,[Symbol.iterator]() {let current = this.start;return {next: () => ({value: current,done: current++ > this.end})};}
};for (const num of range) {console.log(num); // 1, 2, 3, 4, 5
}
六、注意事項
-
JSON 序列化
Symbol 屬性會被?JSON.stringify()
?忽略:const obj = { [Symbol('key')]: 'value' }; console.log(JSON.stringify(obj)); // {}
-
類型轉換
Symbol 無法隱式轉換為字符串或數值,需顯式調用?toString()
:const sym = Symbol('desc'); console.log(String(sym)); // "Symbol(desc)" console.log(sym + ''); // ? TypeError: Cannot convert a Symbol to a string
-
跨 Realm 共享
不同 iframe 或 Web Worker 中的全局 Symbol 注冊表是隔離的,需通過?postMessage
?顯式傳遞。
七、總結
特性 | 說明 |
---|---|
唯一性 | 每個 Symbol 值唯一,避免命名沖突 |
不可變性 | 創建后無法修改,不可通過?new ?實例化 |
私有性 | 通過 Symbol 鍵模擬私有屬性(需配合模塊作用域) |
內置 Symbol | 改變對象默認行為(如迭代、類型標簽) |
Symbol 的核心價值?在于提供了一種安全、可控的元編程機制,適用于庫開發、框架設計及復雜對象行為定制。
? ?
BigInt類型
BigInt?是 JavaScript 中用于表示?任意精度大整數?的數據類型,解決了傳統?
Number
?類型在超過?2^53 - 1
(即?Number.MAX_SAFE_INTEGER
)時的精度丟失問題。
一、BigInt 的核心特性
1.?定義與語法
-
字面量表示法:在數字后加?
n
。const bigInt = 9007199254740993n; // 超過 Number 的安全整數范圍
-
構造函數轉換:通過?
BigInt()
?轉換其他類型。const fromString = BigInt("12345678901234567890"); const fromNumber = BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
2.?類型檢測
-
使用?
typeof
?檢測返回?"bigint"
。typeof 123n; // "bigint"
3.?數值范圍
-
無固定上限:僅受內存限制,可表示任意大的整數。
-
不支持小數:BigInt 僅用于整數,小數部分會被截斷。
BigInt(3.9); // 3n(直接截斷,非四舍五入)
二、BigInt 的運算規則
1.?算術運算
支持常規運算符(+
、-
、*
、**
、/
、%
),但除法返回整數部分。
const a = 10n;
const b = 3n;
console.log(a / b); // 3n(舍去小數)
2.?比較運算
可與?Number
?或其他?BigInt
?進行比較(==
、===
、>
、<
?等)。
10n === 10; // false(類型不同)
10n == 10; // true(值相等)
10n > 5; // true
3.?位運算
支持位操作符(&
、|
、^
、<<
、>>
),但操作數必須同為?BigInt
。
const mask = 0b1111n;
const result = 0b1010n & mask; // 0b1010n & 0b1111n → 0b1010n(即 10n)
4.?禁止混合運算
BigInt 與 Number 不可直接運算,需顯式轉換。
// 10n + 5; // ? TypeError: Cannot mix BigInt and other types
10n + BigInt(5); // ? 15n
三、BigInt 的創建與轉換
1.?類型轉換
-
字符串轉 BigInt:
BigInt("123"); // 123n BigInt("0xFF"); // 255n(支持十六進制) BigInt("0b1010"); // 10n(支持二進制)
-
Number 轉 BigInt:
BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
2.?類型強制轉換
-
隱式轉換:部分操作(如模板字符串)會隱式調用?
toString()
。`Value: ${100n}`; // "Value: 100"
-
顯式轉換:
Number(100n); // 100(可能丟失精度) Boolean(0n); // false(0n 為假值)
四、BigInt 的應用場景
1.?高精度整數計算
處理金融、加密算法中的大整數運算:
const largePrime = 957496696762772407663n;
const hash = largePrime * 2654435761n; // 避免溢出
2.?時間戳與唯一ID
生成高精度時間戳或分布式唯一ID:
const timestamp = BigInt(Date.now()) * 1000000n + process.hrtime.bigint();
3.?數學庫與算法
實現大數階乘、斐波那契數列等:
function factorial(n) {let result = 1n;for (let i = 2n; i <= n; i++) {result *= i;}return result;
}
console.log(factorial(20n)); // 2432902008176640000n
五、注意事項與兼容性
1.?兼容性
-
支持環境:現代瀏覽器(Chrome 67+、Firefox 68+、Node.js 10.4+)。
-
Polyfill:無完美 Polyfill,可通過第三方庫(如?
big-integer
)模擬。
2.?JSON 序列化
BigInt 無法直接通過?JSON.stringify()
?序列化,需自定義轉換:
const data = { id: 12345678901234567890n };
const json = JSON.stringify(data, (key, value) =>typeof value === 'bigint' ? value.toString() : value
);
// {"id":"12345678901234567890"}
3.?Math 對象方法
BigInt 不支持?Math
?方法(如?Math.pow()
),需手動實現:
function pow(base, exponent) {return base ** exponent; // 使用 ** 運算符
}
pow(2n, 10n); // 1024n
4.?性能考量
-
內存占用:BigInt 比 Number 占用更多內存,需謹慎處理超大數值。
-
運算速度:BigInt 運算通常慢于 Number,高頻計算時需評估性能。
六、示例代碼
1.?大數計算
const maxSafe = Number.MAX_SAFE_INTEGER; // 9007199254740991
const unsafe = maxSafe + 2; // 9007199254740992(精度丟失)
const safe = BigInt(maxSafe) + 2n; // 9007199254740993n(精確)
2.?類型檢測與轉換
const big = 100n;
if (typeof big === 'bigint') {const num = Number(big); // 轉換為 Number(可能丟失精度)
}
七、總結
特性 | BigInt | Number |
---|---|---|
整數范圍 | 任意精度 | ±(2^53 - 1) |
小數支持 | 否 | 是(雙精度浮點數) |
運算符兼容 | 需與同類型運算,禁止混合 | 支持常規運算 |
內存占用 | 較高 | 較低 |
適用場景 | 大整數計算、加密、高精度ID | 常規數值運算 |
BigInt 的核心價值在于解決 JavaScript 中?大整數精度丟失?的問題,適用于科學計算、密碼學等領域。使用時需注意兼容性、類型轉換及性能影響。