JavaScript高级面试题:深拷贝与浅拷贝、闭包解析

需积分: 0 0 下载量 54 浏览量 更新于2024-08-04 收藏 9KB MD 举报
"JavaScript 高级阶段面试题,包括值类型和引用类型的区别,深拷贝与浅拷贝的概念及实现,以及闭包的理解和应用。" 在 JavaScript 中,值类型和引用类型是两种基本的数据存储方式,它们具有显著的区别: 1. **值类型**: - 基本类型数据(如 number, string, boolean, null, undefined, symbol)被视为值类型。 - 当值类型被赋值或复制时,实际上是拷贝了实际的值。 - 使用 `typeof` 操作符可以检测一个变量是否为值类型。 2. **引用类型**: - 引用类型主要指的是对象(Object),包括数组、函数、日期等。 - 在赋值或复制引用类型时,拷贝的是对象的引用(指针),而不是对象本身。 - 检测一个变量是否为引用类型通常使用 `instanceof` 或者 `Object.prototype.toString.call()` 方法。 - 引用类型可以通过 `new` 关键字来构造。 **深拷贝与浅拷贝**是关于对象复制的重要概念: - **浅拷贝**只复制对象的第一层属性,如果对象内部包含其他对象,拷贝的是这些内嵌对象的引用。因此,修改拷贝后的对象会影响到原始对象,适用于属性值为简单数据类型的情况。 - **深拷贝**则会递归地复制对象及其所有嵌套的对象,确保即使修改拷贝后的对象,也不会影响到原始对象。实现深拷贝的方法包括递归、JSON.parse 和 JSON.stringify(有局限性)以及某些库函数,如 Lodash 的 `_.cloneDeep`。 例如,下面的 JavaScript 代码展示了浅拷贝和深拷贝的实现: ```js // 浅拷贝示例 var obj = { class: 'UI', age: 20, love: 'eat' }; function getObj(obj) { var newObj = {}; for (var key in obj) { newObj[key] = obj[key]; } return newObj; } var obj2 = getObj(obj); console.log(obj2); // 深拷贝示例 var obj = { class: '前端', age: 26, love: { fruits: 'apple', meat: 'beef' } }; function getObj(obj) { var newObj = {}; for (var key in obj) { newObj[key] = typeof obj[key] === 'object' ? getObj(obj[key]) : obj[key]; } return newObj; } var obj2 = getObj(obj); console.log(obj2); ``` **闭包**是 JavaScript 中的一个关键特性,它指的是一个函数可以访问其自身作用域以及包含它的外部作用域中的变量,即使在其外部作用域的变量已经被销毁的情况下。这使得闭包可以用来创建私有变量和持久化数据。 优点: 1. 创建私有变量,防止全局变量污染。 2. 保持变量状态,实现数据持久化。 缺点: 1. 由于闭包会保留对外部变量的引用,可能导致内存泄漏。 解决方法: 1. 减少不必要的函数嵌套,避免过多的变量引用。 2. 不再需要闭包时,将引用置为 `null`,以便垃圾回收器可以释放内存。 闭包的一个经典例子是计数器: ```js function counter() { let count = 0; return function() { return count++; }; } const increment = counter(); console.log(increment()); // 0 console.log(increment()); // 1 ``` 在这个例子中,`counter` 函数返回了一个内部函数,这个内部函数形成了一个闭包,可以访问并更新外部的 `count` 变量。