博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript闭包的个人理解
阅读量:6146 次
发布时间:2019-06-21

本文共 1819 字,大约阅读时间需要 6 分钟。

闭包一词在javascript中非常有名,对于前端来说理解它至关重要,很多高级应用都要依靠闭包实现。掌握了它,对我们的js写代码水平会有很大帮助,因此成为许多公司前端的面试题之一,用来测试应聘者的js水平,可见其重要性,所以作为一个前端,理解闭包是必须的!没有任何理由说不懂!

理解闭包,首先必须理解变量作用域和作用域链。在JavaScript中,JavaScript有两种作用域:全局作用域和函数作用域。函数内部可以直接读取全局变量。函数子作用域可以访问父作用域的变量 。

var n = 1;function f1() {  console.log(n);}f1() // 1复制代码

上面代码中,函数f1可以直接访问全局变量n, 但是在函数外部无法直接读取函数内部的变量,

function f1() {  var n = 1;}console.log(n)//Uncaught ReferenceError: n is not defined  提示n没有定义复制代码

如果出于种种原因,需要得到函数内的局部变量。正常情况下,这是办不到的,只有通过变通方法才能实现。那就是在函数的内部,再定义一个函数。

function f1() {  var n = 1;  function f2() {  console.log(n); // 1  }}复制代码

上面代码中,函数f2就在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。子对象会顺着作用域链找父对象的变量, 如果想要函数外部访问函数内部的变量,那么可以使用return把f2作为返回值,不就可以在发外部访问到内部的变量了吗?

function f1() {  var n = 1;  function f2() {  console.log(n); // 1  }  return f2}var result = f1();result(); // 1复制代码

上面代码中,函数f1的返回值就是函数f2,由于f2可以读取f1的内部变量,所以就可以在外部获得f1的内部变量了。 f2就是闭包,。闭包是指有权访问另一个函数作用域中的变量的函数。在这里要注意的一点:由于通常闭包都是匿名函数,所以给人造成错觉,只有匿名函数才能作为闭包,其实,命名、匿名函数都是可以作为闭包函数的,只不过通常闭包都是作为返回值,自身很少被调用,所以也就没了命名的必要,而命名函数基本上都是要调用的。

另外看了网上一些文章,是通过作用域的提升来解释的, f1是一级作用域,f2是二级作用域,f1返回f2后,把f2的作用域提升到一级作用域,就可以在外部被全局调用了,这种说法通俗易懂,很好理解,但是

闭包的优点

1.函数内部的定义的变量可以保存在内存中。一般函数运行后,函数内部的变量就会被销毁,但是由于闭包的存在,该函数内部的变量就不会被销毁回收,如上述代码中,f1调用后,闭包f2会调用变量n,使得n始终存在内存中。 2.避免全局变量的污染,全局变量是可重用但是污染全局,局部变量不会污染全局但是不可重用。而闭包就是二者优点的结合, 3.是封装对象的私有属性和私有方法。举例如下:

function Person(name) {  var _age;  function setAge(n) {    _age = n;  }  function getAge() {    return _age;  }  return {    name: name,    getAge: getAge,    setAge: setAge  };}var p1 = Person('张三');p1.setAge(25);p1.getAge() // 25该例子来源与阮一峰的博客函数闭包内容,复制代码

上面代码中,函数Person的内部变量_age,通过闭包getAge和setAge,变成了返回对象p1的私有变量。

闭包的缺点

闭包会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。

备注:之前闭包在iE浏览器上存在内存溢出的问题,不过这是由于ie的垃圾回收机制引起的,目前已经修复这个问题,

转载于:https://juejin.im/post/5cb050065188251acc5390da

你可能感兴趣的文章
Android打包常见错误之Export aborted because fatal lint errors were found
查看>>
Tar打包、压缩与解压缩到指定目录的方法
查看>>
配置spring上下文
查看>>
Python异步IO --- 轻松管理10k+并发连接
查看>>
Oracle中drop user和drop user cascade的区别
查看>>
登记申请汇总
查看>>
Office WORD如何取消开始工作右侧栏
查看>>
Android Jni调用浅述
查看>>
CodeCombat森林关卡Python代码
查看>>
第一个应用程序HelloWorld
查看>>
(二)Spring Boot 起步入门(翻译自Spring Boot官方教程文档)1.5.9.RELEASE
查看>>
Java并发编程73道面试题及答案
查看>>
企业级负载平衡简介(转)
查看>>
ICCV2017 论文浏览记录
查看>>
科技巨头的交通争夺战
查看>>
当中兴安卓手机遇上农行音频通用K宝 -- 卡在“正在通讯”,一直加载中
查看>>
Shell基础之-正则表达式
查看>>
JavaScript异步之Generator、async、await
查看>>
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>