如何去理解 Javascript 的闭包?相比没闭包,有特什么别的差别? - V2EX
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 3320 次点击
    这是一个创建于 3799 天前的主题,其中的信息可能已经有所发展或是发生改变。
    能用简单的语言,讲明白这个特性,能带来什么么?引入他,和没有引入差别是什么?
    有什么应用?如果不存在闭包,该如何实现闭包能办到的事情呢?
    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     Solana     2664 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 92ms UTC 15:13 PVG 23:13 LAX 07:13 JFK 10:13
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86