一、数据类型分类(必背)
JavaScript 数据类型分为原始类型和引用类型:
1. 原始类型(Primitive)
undefinednullbooleannumberstringsymbol(ES6)bigint(ES2020)
2. 引用类型(Reference)
Object(包括数组、函数、日期等)ArrayFunctionDateRegExp正则表达式
二、区别
| 维度 | 原始类型 | 引用类型 |
|---|---|---|
| 存储方式 | 值直接存储在栈内存中 | 值存储在堆内存,引用存储在栈中 |
| 比较方式 | 值相等(===) | 引用地址相等(即使值相同) |
| 可变性 | 不可变(修改会创建新值) | 可变(直接修改原对象) |
| 传递方式 | 按值传递(副本) | 按引用传递(共享同一对象) |
| 内置方法 | 通过包装对象访问(如 'a'.toUpperCase()) | 直接拥有方法(如 [].push()) |
三、问题
1. typeof vs instanceof 的区别
-
typeof
- 返回一个表示类型的字符串(如
'object'、'function')。 - 局限性:
typeof null; // 'object'(历史遗留问题) typeof []; // 'object' typeof new Date(); // 'object'
- 返回一个表示类型的字符串(如
-
instanceof
- 判断对象是否是某个构造函数的实例(通过原型链)。
- 示例:
[] instanceof Array; // true [] instanceof Object; // true(所有对象继承自 Object)
2. null 和 undefined 的区别
-
null
- 表示“有意为之的空值”,需主动赋值(如
let a = null)。 typeof null返回'object'(历史设计错误)。
- 表示“有意为之的空值”,需主动赋值(如
-
undefined
- 表示“未定义”或“缺少值”(如变量声明未赋值、函数无返回值)。
typeof undefined返回'undefined'。
3. 如何判断一个变量是数组?
-
最优解:
Array.isArray(arr); // true/false -
其他方法:
arr instanceof Array; // 需注意跨窗口问题 Object.prototype.toString.call(arr) === '[object Array]'; // 最准确
4. 简述 Symbol 的用途
- 唯一性:创建独一无二的键,避免命名冲突。
- 应用场景:
- 作为对象私有属性:
const key = Symbol('private'); const obj = { [key]: 'secret' }; - 自定义迭代器:
obj[Symbol.iterator] = function() { /* ... */ };
- 作为对象私有属性:
5. BigInt 的作用与注意事项
- 作用:处理超过
Number.MAX_SAFE_INTEGER的大整数。 - 语法:
const num = 12345678901234567890n; // 后缀 n 表示 BigInt - 注意:
- 不能与普通数字直接运算(需转换)。
typeof 123n返回'bigint'。
四、类型转换机制
1. 显式转换
-
Number():
Number('123'); // 123 Number('abc'); // NaN -
String():
String(123); // '123' String(true); // 'true' -
Boolean():
- 假值:
false、0、''、null、undefined、NaN。 - 真值:其他所有值。
- 假值:
2. 隐式转换(重点)
-
加法运算(+):
1 + '2'; // '12'(字符串拼接优先) true + 1; // 2(布尔转为数字) -
比较运算(==):
1 == '1'; // true(类型转换后比较) null == undefined; // true(特殊规则) -
最佳实践:优先使用
===进行严格比较,避免隐式转换。