一、数据类型与类型判断
JavaScript 数据类型分为原始类型和引用类型:
- 原始类型:
number、string、boolean、undefined、null(ES6前)、symbol、bigint。 - 引用类型:
object、function、array、Date、Map、Set、RegExp等。
类型判断方法
-
typeof:
- 可识别原始类型(
typeof null返回"object")。 - 引用类型中仅
function返回"function",其余返回"object"。
typeof 42; // "number" typeof {}; // "object" typeof function(){};// "function" - 可识别原始类型(
-
instanceof:
- 基于原型链判断对象类型。
[] instanceof Array; // true -
Object.prototype.toString:
- 返回
[object Type]格式字符串,精准识别类型。
Object.prototype.toString.call([]); // "[object Array]" - 返回
二、类型转换与隐式陷阱
显示转换
- 转字符串:
String(x)或x.toString()。 - 转数字:
Number(x)(parseInt/parseFloat更安全)。 - 转布尔值:
Boolean(x)(0、""、null、undefined、NaN为假值)。
隐式转换
-
运算符触发:
+、-、==、if等。"5" + 3; // "53"(字符串拼接) "5" - 2; // 3(数字运算) [] == 0; // true([]转空字符串→转0) -
引用类型转原始类型:
- 优先调用
valueOf(),若返回原始值则结束。 - 否则调用
toString()。
{} + ""; // "[object Object]" [1,2] + 3; // "1,23" - 优先调用
经典问题:0.1 + 0.2 ≠ 0.3
- 原因:浮点数精度丢失(二进制无法精确表示十进制小数)。
- 解决:使用
toFixed(2)或转为整数计算。
三、闭包与作用域
闭包定义
函数内部定义的函数引用外部变量,形成闭包,延长外部函数变量的生命周期。
function outer() {
let count = 0;
return function() {
return ++count;
};
}
const counter = outer();
counter(); // 1
闭包应用
- 模块化封装私有变量。
- 防抖/节流函数。
四、拷贝:浅拷贝 vs 深拷贝
-
浅拷贝:仅复制一层属性(引用类型共享地址)。
const obj2 = Object.assign({}, obj1); const arr2 = [...arr1]; -
深拷贝:递归复制所有层级属性。
- JSON法:
JSON.parse(JSON.stringify(obj))(无法处理函数、undefined)。 - 递归法:手动遍历对象属性。
- MessageChannel:跨线程传递实现深拷贝。
- JSON法:
五、原型与继承
原型链机制
- 显示原型:
prototype(构造函数属性)。 - 隐式原型:
__proto__(实例属性,指向构造函数的prototype)。 - 原型链查找:对象属性查找沿
__proto__链向上,直到null。
继承实现
-
组合继承(最常用):
function Parent(name) { this.name = name; } function Child(name) { Parent.call(this, name); } Child.prototype = Object.create(Parent.prototype); -
Class继承(ES6):
class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name) { super(name); } }
六、异步与事件循环
异步方案演进
- 回调函数:易导致回调地狱。
- Promise:链式调用解决嵌套问题。
- async/await:同步写法处理异步逻辑。
Event Loop机制
- 宏任务:
script、setTimeout、setInterval、I/O。 - 微任务:
Promise.then、MutationObserver。 - 执行顺序:同步代码 → 微任务队列 → 宏任务队列。
console.log("1"); // 同步
setTimeout(() => console.log("2"), 0); // 宏任务
Promise.resolve().then(() => console.log("3")); // 微任务
// 输出顺序:1 → 3 → 2
七、高频面试题
-
var、let、const区别:
var无块级作用域,存在变量提升。let/const有块级作用域,存在暂时性死区。
-
== vs ===:
==隐式转换类型后比较值。===严格比较值和类型。
-
new操作符原理:
- 创建空对象 → 链接原型 → 绑定this → 执行构造函数 → 返回对象。
-
Proxy应用场景:
- Vue3响应式系统、属性校验、日志拦截。
总结
JavaScript核心概念涵盖数据类型、作用域、异步处理等,理解其底层机制是面试成功的关键。通过结合代码示例与原理分析,可系统掌握高频考点,从容应对技术面试。