1. JavaScript 基本数据类型概述JavaScript 作为一门动态弱类型语言其数据类型系统与其他编程语言有着显著差异。在 JavaScript 中数据类型可以分为两大类原始类型Primitive types和对象类型Object type。理解这些数据类型及其区别是掌握 JavaScript 编程的基础。原始类型包括UndefinedNullBooleanNumberBigIntStringSymbol这些原始类型的值是不可变的immutable这意味着一旦创建就无法直接修改其值。当我们对原始类型变量进行操作时实际上是在创建新的值而不是修改原有值。对象类型则是可变的mutable包括ObjectArrayFunctionDateRegExp 等注意虽然 typeof null 返回 object但这被认为是 JavaScript 的一个历史遗留错误null 实际上是原始类型。2. 原始数据类型详解2.1 Undefined 类型Undefined 类型只有一个值undefined。它表示变量已声明但尚未被赋值或者函数没有明确返回值时的默认返回值。let x; console.log(x); // undefined function foo() {} console.log(foo()); // undefined在实际开发中我们应尽量避免直接使用 undefined 值而是通过变量声明但不赋值的方式让 JavaScript 引擎自动赋予 undefined。2.2 Null 类型Null 类型也只有一个值null。它表示有意地缺少任何对象值。与 undefined 不同null 需要显式赋值。let y null; console.log(y); // nullnull 常用于以下场景初始化一个可能被赋值为对象的变量表示函数的参数不是对象表示对象原型链的终点如 Object.prototype.proto null2.3 Boolean 类型Boolean 类型有两个值true 和 false。它常用于条件判断和逻辑运算。let isActive true; let isCompleted false; if (isActive) { console.log(Active); }JavaScript 中所有值都可以转换为布尔值。以下值会被转换为 false称为 falsy 值false0 (空字符串)nullundefinedNaN其他所有值都会被转换为 truetruthy 值。2.4 Number 类型Number 类型采用 IEEE 754 64位双精度浮点数格式表示。它能够表示的范围大约是 ±5.0 × 10⁻³²⁴ 到 ±1.8 × 10³⁰⁸。let integer 42; let float 3.14159; let scientific 2.998e8; // 2.998 × 10^8特殊数值Infinity 和 -Infinity表示数学上的无穷大NaNNot a Number表示无效的数学运算结果console.log(1 / 0); // Infinity console.log(Math.sqrt(-1)); // NaN注意JavaScript 中所有数字都以浮点数形式存储整数只是没有小数部分的特殊情况。2.5 BigInt 类型BigInt 是 ES2020 引入的新类型用于表示任意精度的整数。通过在数字后加 n 后缀或调用 BigInt() 函数创建。const bigInt 9007199254740991n; const alsoBigInt BigInt(9007199254740991); console.log(bigInt 1n); // 9007199254740992nBigInt 主要用于超出 Number 安全整数范围±(2⁵³ - 1)的计算。2.6 String 类型String 类型表示文本数据使用 UTF-16 编码。字符串可以用单引号()、双引号()或反引号()表示。let str1 Hello; let str2 World; let template Hello ${str2}; // 模板字符串字符串是不可变的任何修改字符串的操作都会创建新字符串。2.7 Symbol 类型Symbol 是 ES6 引入的原始类型表示唯一的标识符。常用于对象属性的键以避免属性名冲突。const sym1 Symbol(); const sym2 Symbol(description); // 可选的描述字符串 console.log(sym1 sym2); // falseSymbol 的主要用途创建唯一的对象属性键实现自定义的迭代行为定义众所周知的 Symbol如 Symbol.iterator3. 对象类型Object对象是属性的集合属性由键值对组成。对象可以通过字面量、new 操作符或 Object.create() 创建。// 对象字面量 const person { name: Alice, age: 30, greet() { console.log(Hello, Im ${this.name}); } }; // 使用 new 操作符 const date new Date(); // 使用 Object.create() const protoObj { x: 1 }; const obj Object.create(protoObj);对象属性可以是数据属性或访问器属性getter/setter。数据属性有四个特性value属性的值writable是否可修改enumerable是否可枚举configurable是否可删除或修改特性4. 数据类型检测与转换4.1 类型检测typeof 操作符可以检测原始类型除 null 外和函数console.log(typeof undefined); // undefined console.log(typeof null); // object (历史遗留问题) console.log(typeof true); // boolean console.log(typeof 42); // number console.log(typeof 42n); // bigint console.log(typeof hello); // string console.log(typeof Symbol()); // symbol console.log(typeof {}); // object console.log(typeof []); // object console.log(typeof function(){}); // function检测数组可以使用 Array.isArray()console.log(Array.isArray([])); // true console.log(Array.isArray({})); // false4.2 类型转换JavaScript 是弱类型语言会自动进行类型转换。我们也可以显式转换// 转换为字符串 console.log(String(123)); // 123 console.log(123 ); // 123 // 转换为数字 console.log(Number(123)); // 123 console.log(123); // 123 console.log(parseInt(123px)); // 123 console.log(parseFloat(3.14)); // 3.14 // 转换为布尔值 console.log(Boolean(1)); // true console.log(!!1); // true console.log(Boolean(0)); // false5. 数据类型的内存管理理解 JavaScript 数据类型在内存中的存储方式对于编写高效代码至关重要。5.1 原始类型的存储原始类型值直接存储在栈内存中访问速度快但大小固定。当我们将原始类型赋值给变量或传递给函数时实际上是传递值的副本。let a 10; let b a; // b 是 a 的副本 a 20; console.log(b); // 10 (不受 a 变化的影响)5.2 对象类型的存储对象类型值存储在堆内存中变量存储的是对象的引用内存地址。当复制对象变量或将其传递给函数时传递的是引用而非实际对象。let obj1 { x: 10 }; let obj2 obj1; // obj2 和 obj1 引用同一个对象 obj1.x 20; console.log(obj2.x); // 20 (受 obj1 变化的影响)5.3 垃圾回收JavaScript 使用自动垃圾回收机制。对于不再被引用的对象垃圾回收器会自动释放其占用的内存。了解这一点有助于避免内存泄漏function createObjects() { const tempObj {}; // 临时对象 // 函数执行完毕后tempObj 不再被引用会被回收 }6. 数据类型的最佳实践6.1 选择合适的数据类型对于简单的标志或开关使用 Boolean对于整数和小数使用 Number对于大整数使用 BigInt对于文本使用 String对于唯一标识符使用 Symbol对于复杂数据结构使用 Object 或特定对象类型如 Array、Map6.2 避免的类型陷阱浮点数精度问题console.log(0.1 0.2 0.3); // false // 解决方案使用整数运算或将结果四舍五入NaN 的特殊性console.log(NaN NaN); // false // 正确检测 NaN 的方法 console.log(Number.isNaN(NaN)); // truenull 和 undefined 的混淆// 明确区分变量未定义和有意为空 let missingValue null; // 明确表示没有值6.3 性能考虑对于大量相似数据的集合考虑使用类型化数组TypedArray避免频繁创建和销毁大型对象对于键值对集合根据需求选择 Object、Map 或 WeakMap7. ES6 新增数据类型特性7.1 Symbol 的进阶用法Symbol 可以用于创建对象的私有属性const _private Symbol(private); class MyClass { constructor() { this[_private] secret; } getSecret() { return this[_private]; } } const instance new MyClass(); console.log(instance.getSecret()); // secret console.log(instance[_private]); // 可以访问但不是真正的私有7.2 BigInt 的运算限制BigInt 不能与 Number 直接混合运算const big 100n; const num 50; // console.log(big num); // 报错 console.log(big BigInt(num)); // 150n7.3 模板字符串的高级用法模板字符串支持标签函数可以创建 DSL领域特定语言function highlight(strings, ...values) { return strings.reduce((result, str, i) { return ${result}${str}mark${values[i] || }/mark; }, ); } const name Alice; const age 30; const html highlightHello ${name}, you are ${age} years old.; console.log(html); // Hello markAlice/mark, you are mark30/mark years old.
JavaScript数据类型详解:从基础到内存管理
1. JavaScript 基本数据类型概述JavaScript 作为一门动态弱类型语言其数据类型系统与其他编程语言有着显著差异。在 JavaScript 中数据类型可以分为两大类原始类型Primitive types和对象类型Object type。理解这些数据类型及其区别是掌握 JavaScript 编程的基础。原始类型包括UndefinedNullBooleanNumberBigIntStringSymbol这些原始类型的值是不可变的immutable这意味着一旦创建就无法直接修改其值。当我们对原始类型变量进行操作时实际上是在创建新的值而不是修改原有值。对象类型则是可变的mutable包括ObjectArrayFunctionDateRegExp 等注意虽然 typeof null 返回 object但这被认为是 JavaScript 的一个历史遗留错误null 实际上是原始类型。2. 原始数据类型详解2.1 Undefined 类型Undefined 类型只有一个值undefined。它表示变量已声明但尚未被赋值或者函数没有明确返回值时的默认返回值。let x; console.log(x); // undefined function foo() {} console.log(foo()); // undefined在实际开发中我们应尽量避免直接使用 undefined 值而是通过变量声明但不赋值的方式让 JavaScript 引擎自动赋予 undefined。2.2 Null 类型Null 类型也只有一个值null。它表示有意地缺少任何对象值。与 undefined 不同null 需要显式赋值。let y null; console.log(y); // nullnull 常用于以下场景初始化一个可能被赋值为对象的变量表示函数的参数不是对象表示对象原型链的终点如 Object.prototype.proto null2.3 Boolean 类型Boolean 类型有两个值true 和 false。它常用于条件判断和逻辑运算。let isActive true; let isCompleted false; if (isActive) { console.log(Active); }JavaScript 中所有值都可以转换为布尔值。以下值会被转换为 false称为 falsy 值false0 (空字符串)nullundefinedNaN其他所有值都会被转换为 truetruthy 值。2.4 Number 类型Number 类型采用 IEEE 754 64位双精度浮点数格式表示。它能够表示的范围大约是 ±5.0 × 10⁻³²⁴ 到 ±1.8 × 10³⁰⁸。let integer 42; let float 3.14159; let scientific 2.998e8; // 2.998 × 10^8特殊数值Infinity 和 -Infinity表示数学上的无穷大NaNNot a Number表示无效的数学运算结果console.log(1 / 0); // Infinity console.log(Math.sqrt(-1)); // NaN注意JavaScript 中所有数字都以浮点数形式存储整数只是没有小数部分的特殊情况。2.5 BigInt 类型BigInt 是 ES2020 引入的新类型用于表示任意精度的整数。通过在数字后加 n 后缀或调用 BigInt() 函数创建。const bigInt 9007199254740991n; const alsoBigInt BigInt(9007199254740991); console.log(bigInt 1n); // 9007199254740992nBigInt 主要用于超出 Number 安全整数范围±(2⁵³ - 1)的计算。2.6 String 类型String 类型表示文本数据使用 UTF-16 编码。字符串可以用单引号()、双引号()或反引号()表示。let str1 Hello; let str2 World; let template Hello ${str2}; // 模板字符串字符串是不可变的任何修改字符串的操作都会创建新字符串。2.7 Symbol 类型Symbol 是 ES6 引入的原始类型表示唯一的标识符。常用于对象属性的键以避免属性名冲突。const sym1 Symbol(); const sym2 Symbol(description); // 可选的描述字符串 console.log(sym1 sym2); // falseSymbol 的主要用途创建唯一的对象属性键实现自定义的迭代行为定义众所周知的 Symbol如 Symbol.iterator3. 对象类型Object对象是属性的集合属性由键值对组成。对象可以通过字面量、new 操作符或 Object.create() 创建。// 对象字面量 const person { name: Alice, age: 30, greet() { console.log(Hello, Im ${this.name}); } }; // 使用 new 操作符 const date new Date(); // 使用 Object.create() const protoObj { x: 1 }; const obj Object.create(protoObj);对象属性可以是数据属性或访问器属性getter/setter。数据属性有四个特性value属性的值writable是否可修改enumerable是否可枚举configurable是否可删除或修改特性4. 数据类型检测与转换4.1 类型检测typeof 操作符可以检测原始类型除 null 外和函数console.log(typeof undefined); // undefined console.log(typeof null); // object (历史遗留问题) console.log(typeof true); // boolean console.log(typeof 42); // number console.log(typeof 42n); // bigint console.log(typeof hello); // string console.log(typeof Symbol()); // symbol console.log(typeof {}); // object console.log(typeof []); // object console.log(typeof function(){}); // function检测数组可以使用 Array.isArray()console.log(Array.isArray([])); // true console.log(Array.isArray({})); // false4.2 类型转换JavaScript 是弱类型语言会自动进行类型转换。我们也可以显式转换// 转换为字符串 console.log(String(123)); // 123 console.log(123 ); // 123 // 转换为数字 console.log(Number(123)); // 123 console.log(123); // 123 console.log(parseInt(123px)); // 123 console.log(parseFloat(3.14)); // 3.14 // 转换为布尔值 console.log(Boolean(1)); // true console.log(!!1); // true console.log(Boolean(0)); // false5. 数据类型的内存管理理解 JavaScript 数据类型在内存中的存储方式对于编写高效代码至关重要。5.1 原始类型的存储原始类型值直接存储在栈内存中访问速度快但大小固定。当我们将原始类型赋值给变量或传递给函数时实际上是传递值的副本。let a 10; let b a; // b 是 a 的副本 a 20; console.log(b); // 10 (不受 a 变化的影响)5.2 对象类型的存储对象类型值存储在堆内存中变量存储的是对象的引用内存地址。当复制对象变量或将其传递给函数时传递的是引用而非实际对象。let obj1 { x: 10 }; let obj2 obj1; // obj2 和 obj1 引用同一个对象 obj1.x 20; console.log(obj2.x); // 20 (受 obj1 变化的影响)5.3 垃圾回收JavaScript 使用自动垃圾回收机制。对于不再被引用的对象垃圾回收器会自动释放其占用的内存。了解这一点有助于避免内存泄漏function createObjects() { const tempObj {}; // 临时对象 // 函数执行完毕后tempObj 不再被引用会被回收 }6. 数据类型的最佳实践6.1 选择合适的数据类型对于简单的标志或开关使用 Boolean对于整数和小数使用 Number对于大整数使用 BigInt对于文本使用 String对于唯一标识符使用 Symbol对于复杂数据结构使用 Object 或特定对象类型如 Array、Map6.2 避免的类型陷阱浮点数精度问题console.log(0.1 0.2 0.3); // false // 解决方案使用整数运算或将结果四舍五入NaN 的特殊性console.log(NaN NaN); // false // 正确检测 NaN 的方法 console.log(Number.isNaN(NaN)); // truenull 和 undefined 的混淆// 明确区分变量未定义和有意为空 let missingValue null; // 明确表示没有值6.3 性能考虑对于大量相似数据的集合考虑使用类型化数组TypedArray避免频繁创建和销毁大型对象对于键值对集合根据需求选择 Object、Map 或 WeakMap7. ES6 新增数据类型特性7.1 Symbol 的进阶用法Symbol 可以用于创建对象的私有属性const _private Symbol(private); class MyClass { constructor() { this[_private] secret; } getSecret() { return this[_private]; } } const instance new MyClass(); console.log(instance.getSecret()); // secret console.log(instance[_private]); // 可以访问但不是真正的私有7.2 BigInt 的运算限制BigInt 不能与 Number 直接混合运算const big 100n; const num 50; // console.log(big num); // 报错 console.log(big BigInt(num)); // 150n7.3 模板字符串的高级用法模板字符串支持标签函数可以创建 DSL领域特定语言function highlight(strings, ...values) { return strings.reduce((result, str, i) { return ${result}${str}mark${values[i] || }/mark; }, ); } const name Alice; const age 30; const html highlightHello ${name}, you are ${age} years old.; console.log(html); // Hello markAlice/mark, you are mark30/mark years old.