JavaScript深入理解闭包及应用
闭包是前端JavaScript中一个较难的知识点,也是很重要的知识点,如果想要深入理解前端知识架构,执着于对技术的探知,闭包一定要搞懂。
在学习闭包之前要了解一些预编译和作用域链的知识,这之间都是有联系的。
作用域链是AO(Activation Object)和GO(Global Object)构成的链。
AO是从函数调用开始创建,到函数调用结束时销毁。GO是从见到JS代码开始创建,到网页关闭时销毁。
作用域链每个函数都有,每个函数在定义(函数声明\函数表达式)时会拷贝其父函数的作用域链,在函数被调用时,生成AO然后将AO压入作用域链的栈顶。
闭包就是用到了作用域链的特性。
闭包说直白点就是能够读取其他函数内部变量的函数,本质上就是函数外部和函数内部连接的桥梁。
先看一个示例:
function createCounter(){
var count = 0;
function counterAdd(){
count++;
console.log(count);
return count;
}
return counterAdd;
}
var counter = createCounter();
counter();
这就是个典型的闭包示例,counterAdd函数拷贝的是父函数createCounter的作用域链,指向的一直是createCounter的AO,它一直没有被销毁。
函数的AO通过作用域链相互连接起来,使得函数体内的变量都可以保存在函数的AO中,这就是闭包最明显的特性。
闭包的危险:
闭包会造成原有的AO不释放,产生内存泄漏。
内存泄漏是很严重的错误,但是闭包有坏处就有好处,所谓得于斯者毁于斯者。
闭包的应用:
- 实现共有变量
- 缓存存储结构
- 封装,实现属性私有化
- 模块化开发,防止污染全局变量
我们以累加器为例,用代码看一下闭包的应用:
1.实现共有变量
function createCounter(){
var count = 0;
function counterAdd(){
count++;
console.log(count);
return count;
}
return counterAdd;
}
var counter = createCounter();
counter();
counter();
counter();
2.缓存存储结构
function createCounter(){
var count = 0;
function counterAdd(){
count++;
console.log(count);
return count;
}
function counterAddTwo(){
count += 2;
console.log(count);
return count;
}
function clearAction(){
count = 0;
console.log(count);
return count;
}
return [counterAdd,counterAddTwo,clearAction];
}
var counterAction = createCounter();
counterAction[0]();
counterAction[0]();
counterAction[1]();
counterAction[0]();
counterAction[2]();
3.模块化
function createCounter(){
var count = 0;
var counter = {
counterAdd:function(){
count++;
console.log(count);
return count;
},
counterAddTwo:function(){
count += 2;
console.log(count);
return count;
},
clearAction:function(){
count = 0;
console.log(count);
return count;
}
}
return counter;
}
var counter = createCounter();
counter.counterAdd();
counter.counterAddTwo();
counter.counterAdd();
counter.clearAction();
这是闭包三种应用场景,闭包在框架中应用尤为常见,也是面试必问的一环,如果想对技术深耕的同学,最好多加练习,深入理解。闭包的关键还是作用域链的特性造就的。
有问题可以联系QQ:505417246
关注下面微信公众号,可以领取微信小程序、Vue、TypeScript、前端、uni-app、全栈、Nodejs、Python等实战学习资料
相关文章
- 第一百零六节,JavaScript变量作用域及内存
- [Javascript] Hide Properties from Showing Up in "for ... in" Loops in JavaScript
- [Javascript] Create Your First Iterator in JavaScript
- [Javascript] Create an Image with JavaScript Using Fetch and URL.createObjectURL
- [Javascript] Replicate JavaScript Constructor Inheritance with Simple Objects (OLOO)
- [Javascript] Link to Other Objects through the JavaScript Prototype Chain
- [Javascript] Compose multiple functions for new behavior in JavaScript
- [Javascript] Identify and Deal with NaN in JavaScript
- [Javascript] JavaScript Array Methods in Depth - push
- [Javascript] Hoisting in JavaScript
- [Grunt] Concatenating Your Javascript with grunt-contrib-concat
- [Javascript] Coding interview problem: Scheduler functional way
- [Algorithm] JavaScript Graph Data Structure
- [Javascript] Replicate JavaScript Constructor Inheritance with Simple Objects (OLOO)
- [Javascript] Decorators in JavaScript
- JavaScript的语音识别
- 部署在SAP ABAP服务器上的SAP UI5应用的JavaScript文件,是如何被SAP UI5 repository handler处理的
- 超越Web,Javascript在物联网的应用
- python web py入门(20)- javascript的变量
- JavaScript基础语法整理
- 什么是JavaScript