最后
由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
给大家推荐一个实用面试题库
**1、前端面试题库 (**面试必备) 推荐:★★★★★
地址:web前端面试题库
闭包是什么?
- 闭包是指一个函数可以访问并操作其词法作用域外的变量的能力。
- 闭包就是能够读取其他函数内部变量的函数。
- 例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。
- 在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
特点:函数嵌套,并返回子函数,子函数访问了外变量。
//外部函数
function outerFunction() {
//内部函数外的变量
var outerVariable = 'I am from outer function';
//返回内部函数
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
// outerFunction执行完之后被销毁,但是outerVariable被引用着所以仍然活着
var closure = outerFunction();
closure(); // 输出:I am from outer function
闭包的作用?
- 封装私有变量:闭包可以用于创建私有变量和方法。通过在函数内部定义变量,并返回一个内部函数,外部无法直接访问这些变量,从而实现了封装的效果。这样可以避免全局变量的污染,提高代码的可维护性和安全性。
- 延迟执行:闭包可以用于实现延迟执行的效果。通过在函数内部定义一个定时器或事件监听器,并返回一个内部函数,可以在需要的时候触发执行。
- 记忆化/保持状态:闭包可以用于实现记忆化的效果,即将函数的计算结果缓存起来,以便在后续调用时直接返回缓存的结果,提高函数的执行效率。
- 回调函数:闭包可以用于实现回调函数。通过将一个函数作为参数传递给另一个函数,并在内部函数中调用该函数,可以实现异步操作的回调机制。
- 模块化开发:闭包可以用于实现模块化开发。通过将一组相关的变量和方法封装在一个闭包中,可以避免全局命名空间的污染,实现模块的独立性和复用性。
闭包的缺陷?
- 内存占用:闭包会导致外部函数的变量无法被垃圾回收,从而增加内存占用。如果闭包会长时间存在,那么外部变量将无法被释放,可能导致内存泄漏。
- 性能损耗:闭包涉及到作用域链的查找过程,会带来一定的性能损耗。在性能要求高的场景下,需要注意闭包的使用。
闭包的应用场景?
参考链接: js闭包的6种应用场景!!!这下会用了
1. 自执行函数(可以实现单例模式)
let say = (function(){
let val = 'hello world';
function say(){
console.log(val);
}
return say;
})()
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
},
};
})();
2. 防抖节流
// 节流函数封装
function throttle(func, delay) {
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, delay);
}
};
}
// 防抖函数封装
function debounce(func, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
3. 函数柯里化
//柯里化前
function add(a, b, c) {
return a + b + c;
}
console.log(add(1, 2, 3)); //6
//柯里化后
function addCurried1(a) {
return function (b) {
return function (c) {
return a + b + c;
};
};
}
//箭头函数简写
const addCurried2 = (a) => (b) => (c) => a + b + c;
console.log(addCurried1(1)(2)(3)); //6
console.log(addCurried2(1)(2)(3)); //6
4. 发布订阅
function createPubSub() {
// 存储事件及其对应的订阅者
const subscribers = {};
// 订阅事件
function subscribe(event, callback) {
// 如果事件不存在,则创建一个新的空数组
if (!subscribers[event]) {
subscribers[event] = [];
}
// 将回调函数添加到订阅者数组中
subscribers[event].push(callback);
}
// 发布事件
function publish(event, data) {
// 如果事件不存在,则直接返回
if (!subscribers[event]) {
return;
}
// 遍历订阅者数组,调用每个订阅者的回调函数
subscribers[event].forEach((callback) => {
callback(data);
});
}
// 返回订阅和发布函数
return {
subscribe,
publish,
};
}
### 最后
由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
![](https://img-blog.csdnimg.cn/img_convert/bae4e9308ee64c80b661bbaa3f98b678.webp?x-oss-process=image/format,png)
![](https://img-blog.csdnimg.cn/img_convert/49dea8c63420d3932abc9c76d7c4e28e.webp?x-oss-process=image/format,png)
,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
[外链图片转存中...(img-ZtphUv4c-1715150252319)]
[外链图片转存中...(img-Bj7aBhaz-1715150252319)]