V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Mark24
V2EX  ›  JavaScript

如何去理解 JavaScript 的闭包?相比没闭包,有特什么别的差别?

  •  
  •   Mark24 · 2015-08-01 20:11:18 +08:00 via iPhone · 3014 次点击
    这是一个创建于 3437 天前的主题,其中的信息可能已经有所发展或是发生改变。
    能用简单的语言,讲明白这个特性,能带来什么么?引入他,和没有引入差别是什么?
    有什么应用?如果不存在闭包,该如何实现闭包能办到的事情呢?
    13 条回复    2015-08-18 00:08:12 +08:00
    Septembers
        1
    Septembers  
       2015-08-01 20:16:22 +08:00 via Android
    作用域
    an168bang521
        2
    an168bang521  
       2015-08-01 20:23:34 +08:00   ❤️ 2
    一句话:闭包可以避免全局变量的污染;有利于对变量的控制;
    其实闭包原理很简单的,就是开辟一个小的栈内存;也可以理解为,函数执行就是生成一个闭包(作用域);
    但是闭包也有缺点:如果闭包外面有变量接收闭包内的引用类型返回值;那么这个作用域不销毁,浪费浏览器性能;(正常的闭包应该是运行过后,浏览器在空闲的时候销毁)
    Mark24
        3
    Mark24  
    OP
       2015-08-01 20:27:32 +08:00 via iPhone
    @an168bang521 感谢
    w88975
        4
    w88975  
       2015-08-01 20:59:59 +08:00   ❤️ 1
    JS没有class的概念,所以变量是全局的,很容易造成变量的污染,闭包的作用在于,闭包环境内,可以访问全局变量,在闭包环境里定义的变量,类似于class内定义的 private 变量,外部无法访问.
    plqws
        5
    plqws  
       2015-08-01 22:40:08 +08:00
    我想请教个问题: es6 加入了 let 以后是不是就可以抛弃闭包了?
    yanguango
        6
    yanguango  
       2015-08-01 23:14:57 +08:00
    wiki 的第一句话就解释的很清楚了

    In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions.
    FrankFang128
        7
    FrankFang128  
       2015-08-01 23:15:37 +08:00
    闭包是一个自然而然的事情,并不需要刻意学习。
    Mark24
        8
    Mark24  
    OP
       2015-08-03 09:32:22 +08:00   ❤️ 1
    加一条自己的理解:

    闭包,数学上解释,应该就是 “偏函数”,懂数学的人,到这里,用这个概念对照一下,应该秒懂。

    类似 z=f(x,y),z=f(x=6,y),可以传入一个x,等到返回的是一个关于x定值,一个关于y的函数,合适的时候,传入y,就可以求值了

    用途,就是延时计算,根据环境计算,有种动态的意味在里面
    pysama
        9
    pysama  
       2015-08-03 10:37:31 +08:00
    如果没有闭包,在函数外部就无法访问函数里面的局部变量

    所以,闭包的两个作用就是:
    1. 实现访问控制 (读取函数内部变量);
    2. 让一些变量始终保存在内存(利用这个特性时要记得手动释放)。
    Mark24
        10
    Mark24  
    OP
       2015-08-03 10:49:46 +08:00
    @pysama 懒得查了,感觉你好懂,能顺便回答一下,如何手动释放么?
    an168bang521
        11
    an168bang521  
       2015-08-07 23:04:12 +08:00   ❤️ 1
    @Mark24 ,手动释放的事,我个人感觉 @pysama 想说的用该是闭包内,有引用数据类型的变量声明时,当这个变量已经没用的时候,在return前;手动把null 赋给这个值;
    举个例子,可能更容易说明;好比你在写某个函数的时候,函数里需要借用一个数组来协助处理数据;开始写了一句var arr=[];用完后记得要手动写一句 arr=null;
    Mark24
        12
    Mark24  
    OP
       2015-08-08 06:25:45 +08:00 via Android
    beordle
        13
    beordle  
       2015-08-18 00:08:12 +08:00
    @Mark24 你举的例子是函数的科里化,不是闭包,这个要注意,帮你纠正一下。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   988 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:54 · PVG 03:54 · LAX 11:54 · JFK 14:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.