闭包的概念

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

变量的作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域无非就是两种:全局变量和局部变量。

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

var n=999;
function f1(){
  alert(n);
}
f1(); // 999

在函数外部自然无法读取函数内的局部变量。

function f1(){
  var n=999;
}
alert(n); // error

需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!


function f1(){
  n=999;
}
f1();
alert(n); // 999

如何从外部读取局部变量?

出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

那就是在函数的内部,再定义一个函数。


function f1(){
 n=999;
 function f2(){
   alert(n); // 999
 }
}

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。

但是反过来就不行,f2内部的局部变量,对f1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

function f1(){
n=999;
 function f2(){
   alert(n);
 }
 return f2;
}
var result=f1();
result(); // 999

闭包的用途

  • 可以读取函数内部的变量
  • 让这些变量的值始终保持在内存中

闭包的注意点

  • 因为闭包会把函数中的变量始终保存在内存中,内存消耗大,不能滥用,否则会造成性能问题。在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  • 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

Javascript的垃圾回收机制

在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

路漫漫其修远兮,吾将上下而求索~~

浅谈JavaScript--闭包的更多相关文章

  1. 浅谈Javascript闭包

    垃圾回收器 我个人把闭包抽象的称之为”阻止垃圾回收器的函数”或者”有权访问另一个函数内部变量的函数"(当然这个是我个人的理解方式,每个人可能会有不同的理解方式),为什么这样说?这样说还得说说 ...

  2. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  3. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  4. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

  5. 浅谈JavaScript浮点数及其运算

    原文:浅谈JavaScript浮点数及其运算     JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...

  6. 浅谈 JavaScript 编程语言的编码规范

    对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...

  7. 浅谈javascript的原型及原型链

    浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为 ...

  8. 浅谈JavaScript中的null和undefined

    浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...

  9. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  10. 浅谈JavaScript中的内存管理

    一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...

随机推荐

  1. Http请求和响应

    Http请求和响应 Http协议对浏览器发出的Request格式以及对Web服务器发出的Response格式有具体的规定. 请求部分由三部分组成: Requset line:请求行,位于第一行 Req ...

  2. java: jdk1.8以后就不支持桥接的方式

    java: jdk1.8以后就不支持桥接的方式 如果想继续使用桥接的方式,请使用jdk1.7及以下版本.

  3. php: xampp安装对应的phalcon版本(3.2.2-php5.6):比如redis-php5.6, php_igbinary-5.6

    php: xampp安装对应的phalcon版本(3.2.2-php5.6):比如redis-php5.6, php_igbinary-5.6 一.php安装redis扩展   1.使用phpinfo ...

  4. 单机版 RedisPoolUtil({基本操作封装工具类})【一】

    <!--集成的RedisJAR--> <!--引入jedis需的jar包--> <dependency> <groupId>redis.clients& ...

  5. Mybatis异常_04_mapper.xml中不能使用小于号<、大于号>

    一.解决方法: 1.< 2.<![CDATA[ < ]]> 将小于号替换为上述代码即可. 二.参考资料 1.mybatis配置中sql莫名其妙报错,多半是条件中小于符号捣的鬼

  6. YNOI2016 这是我自己的发明

    看到这个标题立刻想到:. “绝地科学家,八倍不屏息啊,八百里外把头打啊...” 首先我们发现如果只考虑第二个操作,这棵树就是假的,我们可以直接莫队解决 如果考虑换根的话...可以把一个操作换成小于等于 ...

  7. 每天一个linux命令(13):more命令

    版权声明更新:2017-05-17博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2. ...

  8. 第k大区间(平均数)--LH

    老师自己出的题,由于没有评测的地方, 我就只说做法啦.(其实是懒得写)(逃ヽ(゚∀゚*)ノ━━━ゥ♪ 以下是个人的见解,如果错了告诉我哦⊙0⊙? 最近特别喜欢用画图写字,,☆⌒(*^-゜)v!

  9. vi查找替换命令详解

    一.查找 查找命令 /pattern<Enter> :向下查找pattern匹配字符串 ?pattern<Enter>:向上查找pattern匹配字符串 使用了查找命令之后,使 ...

  10. POJ 2017 No Brainer(超级水题)

    一.Description Zombies love to eat brains. Yum. Input The first line contains a single integer n indi ...