资讯专栏INFORMATION COLUMN

Js学习笔记:闭包

Crazy_Coder / 1803人阅读

摘要:一前言这个周末,注意力都在学习基础知识上面,刚好看到了闭包这个神圣的东西,所以打算把这两天学到的总结下来,算是巩固自己所学。因此要注意闭包的使用,否则会导致性能问题。五总结闭包的作用能够读取其他函数内部变量。

# 一、前言

这个周末,注意力都在学习基础Js知识上面,刚好看到了闭包这个神圣的东西,所以打算把这两天学到的总结下来,算是巩固自己所学。也可能有些不正确的地方,也请大家看到了,麻烦在评论下提醒一下,算是互相学习了。

二、什么是闭包?
百度百科定义:闭包就是能够读取其他函数内部变量的函数。

在解释之前,得先讲讲作用域。先来看下面这个示例:

var a = 1;
function f(){
  var b = 2;
  console.log(a) // 1
}
console.log(b) // undefined

示例中包含了两种作用域,一种是属于全局的全局作用域,另一种是属于函数f的局部作用域。由于Javascript这种链式作用域(父作用域是可以被其子作用域访问的,而子作用域却不能被父作用域访问)的机制,使得示例最后一行输出了undefined

从此可以看出,无法从父作用域中访问子作用域。而我们再来看闭包的定义:闭包就是能够读取其他函数内部变量的函数。也就是闭包可以让我们从父作用域中访问到子作用域,具体怎么实现的呢?来看这个经典的例子:

function foo(){
    var a = 2;
    function bar(){
        console.log(a);
    }
    return bar;
}

var baz = foo();

baz(); // 2 -> 这就是闭包的效果

这个示例中,闭包就是函数bar。可以看到,我们通过在函数foo内部定义其子函数bar,并将其作为foo返回值,因为bar函数作用域可以访问foo的作用域,所以实现了从全局作用域访问foo函数作用域的效果。

三、闭包的应用

其实,平时你所写的代码中,早就用到了闭包,只是你还没发现而已。

本质上,无论何时何地,如果将函数当作值传递到其他地方使用(非函数所在作用域),你就已经使用了闭包。例如上面示例说的函数bar,我们将他传递到了全局作用域下,通过这种方式访问到本该不能访问的变量a

在定时器、事件监听器、Ajax请求、任何其他异步(或同步)任务中,只要使用了回调函数,实际上就是在使用闭包!

四、注意事项

闭包会让他所在作用域中的变量始终保存在内存中,而不会被垃圾回收机制回收。

function foo(p){
    function bar(){
        console.log(++p);
    }
    return bar;
}

var baz = foo(1);
baz(); // 2
baz(); // 3
baz(); // 4

var bazz = foo(2);

bazz(); // 3
bazz(); // 4
bazz(); // 5

baz(); // 5

看到了没,闭包的使用,函数调用之后,让其外层函数的内部变量(foo函数内的变量)始终保存在了内存中,而不会被回收。

值得注意的是,每次调用一次foo,都会生成一个新的闭包,都会在内存中保存下其外层函数的内部变量。因此要注意闭包的使用,否则会导致性能问题。

五、总结

闭包的作用:

能够读取其他函数内部变量。

让其他函数的内部变量始终保存在内存中。

参考:

阮一峰的Javascript入门教程——闭包

书籍:P43,你不知道的Javascript之闭包——上卷。

附:你不知道的Javascript系列电子书网盘链接, 密码:i8jf

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97292.html

相关文章

  • JS学习笔记——闭包

    摘要:什么是闭包定义我所理解的闭包就是,即使外部函数已经运行完毕,内部函数仍能访问外部函数的作用域中的变量。闭包的应用场景私有变量模块需求只能通过函数提供的方法访问函数内部的变量隐藏。为什么闭包很重要参考资料征服面试什么是闭包 1. 什么是闭包 MDN定义:Closures are functions that refer to independent (free) variables (v...

    Karuru 评论0 收藏0
  • JS学习笔记(第7章)(函数表达式)

    摘要:递归闭包模仿块级作用域私有变量小结在编程中,使用函数表达式可以无需对函数命名,从而实现动态编程。匿名函数也称为拉姆达函数。函数声明要求有名字,但函数表达式不需要。中的函数表达式和闭包都是极其有用的特性,利用它们可以实现很多功能。 1、递归 2、闭包 3、模仿块级作用域 4、私有变量 5、小结 在JavaScript编程中,使用函数表达式可以无需对函数命名,从而实现动态编程。匿名函数也称...

    xiaokai 评论0 收藏0
  • [学习笔记] JavaScript 闭包

    摘要:但是,必须强调,闭包是一个运行期概念。通过原型链可以实现继承,而与闭包相关的就是作用域链。常理来说,一个函数执行完毕,其执行环境的作用域链会被销毁。所以此时,的作用域链虽然销毁了,但是其活动对象仍在内存中。 学习Javascript闭包(Closure)javascript的闭包JavaScript 闭包深入理解(closure)理解 Javascript 的闭包JavaScript ...

    sunsmell 评论0 收藏0
  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0
  • js学习笔记闭包

    摘要:本实例来自语言精粹构造器调用模式闭包变成了私有属性当函数返回时,方法依然可以访问,函数可以访问他被创建时所处山下文环境,这就是闭包。 本实例来自《javascript语言精粹》 构造器调用模式: var Quo = function(string){ this.status = string; }; Quo.prototype.get_status=function(){ ...

    Tony_Zby 评论0 收藏0

发表评论

0条评论

Crazy_Coder

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<