- 浏览: 99389 次
- 性别:
- 来自: 广州
文章分类
最新评论
出处:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
闭包是js语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
一.变量的作用域
要理解闭包,首先必须理解javascript特殊的变量作用域。
变量的作用域有两种:全局变量和局部变量。
js语言的特殊之处,就在于函数内部可以直接读取全局变量。
例如:
Js代码
另外一方面,在函数外部自然无法读取函数内部的局部变量。
Js代码
这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量。
Js代码
二.如何从外部读取局部变量
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数内部再定义一个函数。
Js代码
在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2的局部变量对f1就是不见的。这就是js语言特有的链式作用域结构,子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗?
Js代码
三.闭包的概念
上面代码中的f2函数就是闭包。
一般闭包的定义非常抽象,我个人理解闭包就是能去读取其他函数的内部变量的函数。
由于在js语言中,只有函数内部的字函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
嘿嘿,大概知道了闭包是什么了吧,好的,接下来我们看看闭包的用处。
四、闭包的用途
闭包的用途有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保存在内存中。嘿嘿,保存在内存中,有点新鲜吧。
怎么理解呢,看看如下:
Js代码
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是99,第二次的值是100,这证明了,函数f1中的局部变量一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋予了一个全局变量,这导致f2始终在内存中,而f2的存在依赖f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
五、使用闭包的注意点
1.由于闭包会使得函数中的变量都保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏。解决方法是:在推出函数之前,将不使用的局部变量删除。
2.闭包会在父函数外部,改变父函数内部变量的值,所以,如果你把父函数当作对象使用,把闭包当作它的公用方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。
总结:
闭包就是相当于java中一个类A中声明另一个类B,把类B当成类A的成员变量使用,而类B中的函数相当于类A的方法,类B中的属性就是私有的,类A要用类B的属性,就得声明类B。
闭包是js语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
一.变量的作用域
要理解闭包,首先必须理解javascript特殊的变量作用域。
变量的作用域有两种:全局变量和局部变量。
js语言的特殊之处,就在于函数内部可以直接读取全局变量。
例如:
Js代码
var n = 99; function f1(){ alert(n); } f1();//99
另外一方面,在函数外部自然无法读取函数内部的局部变量。
Js代码
function f1(){ var n = 99; } alert(n); //错误
这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量。
Js代码
function f1(){ n =99; } f1(); alert(n); //99
二.如何从外部读取局部变量
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数内部再定义一个函数。
Js代码
fucntion f1(){ var n =99; function f2(){ alert(n); //99 } }
在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2的局部变量对f1就是不见的。这就是js语言特有的链式作用域结构,子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗?
Js代码
function f1(){ var n=99; function f2(){ alert(n); } return f2; } var result = f1(); result(); //99
三.闭包的概念
上面代码中的f2函数就是闭包。
一般闭包的定义非常抽象,我个人理解闭包就是能去读取其他函数的内部变量的函数。
由于在js语言中,只有函数内部的字函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
嘿嘿,大概知道了闭包是什么了吧,好的,接下来我们看看闭包的用处。
四、闭包的用途
闭包的用途有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保存在内存中。嘿嘿,保存在内存中,有点新鲜吧。
怎么理解呢,看看如下:
Js代码
function f1(){ var n =99; nAdd = function(){n+=1;}; function f2(){ alert(n); } return f2; } var result = f1(); result(); nAdd(); result();
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是99,第二次的值是100,这证明了,函数f1中的局部变量一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋予了一个全局变量,这导致f2始终在内存中,而f2的存在依赖f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
五、使用闭包的注意点
1.由于闭包会使得函数中的变量都保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏。解决方法是:在推出函数之前,将不使用的局部变量删除。
2.闭包会在父函数外部,改变父函数内部变量的值,所以,如果你把父函数当作对象使用,把闭包当作它的公用方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。
总结:
闭包就是相当于java中一个类A中声明另一个类B,把类B当成类A的成员变量使用,而类B中的函数相当于类A的方法,类B中的属性就是私有的,类A要用类B的属性,就得声明类B。
发表评论
-
SQL语句执行浅析
2012-12-17 15:55 909SQL语句主要分为如下4个阶段。 1.Parse(解析)阶段 ... -
JavaScript简单类继承示例
2012-12-14 17:02 775/* 首先给Object类添加继承方法extends ... -
JavaScript四种调用模式
2012-12-12 16:06 856ref:《javascript语言精髓 ... -
关于JavaScript中apply()和call()的方法区别
2012-12-12 16:00 802ref:http://www.cnblogs.com/figh ... -
JavaScript Objcet Literal(字面对象量)总结
2012-12-07 11:03 945首先看看旧模式:基于类的对象构建语法: // 构造器(一般 ... -
[转载]Javascript的this
2012-10-19 14:25 836出处:http://www.ruanyifeng.com/bl ... -
一个Javascript问题
2012-10-19 09:59 731var 变量=函数,不加括号,到底是什么意思。。 本来能理解 ... -
一些密码学知识摘录
2012-10-13 17:28 663出处:http://www.ruanyifeng.com/bl ... -
Javascript获取CSS属性值
2012-10-11 17:31 1598obj.style方法,这个方法只能JS只能获取写在html标 ... -
Javascript 实现检测、添加、移除样式(className)
2012-10-11 17:24 1262出处:http://jawallok.blog.163.com ... -
Javascript的trim()函数实现
2012-09-28 11:22 643原文出处:http://www.cnblogs.com/pen ... -
Java运算符优先级整理
2012-09-22 16:49 832Java 中共有 54 种运算符,按优先级可以分为 14 级, ... -
XML,XML Schema,DTD
2012-08-28 09:29 1127一、摘录出处:http://blo ... -
float与double的位分配
2012-08-25 17:28 0摘自网络:http://zhidao.baidu.com/qu ... -
网络技术文章摘录
2012-08-09 16:33 984数据库相关 事务的acid理解http://www.cnb ...
相关推荐
JavaScript 闭包研究及典型应用 JavaScript 闭包是一种强大的技术,能够在各种场景中发挥重要作用。本文将介绍 JavaScript 闭包的定义、使用场景和典型应用。 闭包函数的定义和使用场景 在 JavaScript 语言中,...
Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性。本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ...
基于JavaScript闭包的Web图片浏览控件的实现 本文主要讲解了基于JavaScript闭包原理的Web图片浏览控件的实现,包括JavaScript闭包概念、闭包应用场景、Web图片浏览控件的设计思路和实现方法。 1. JavaScript闭包...
资源名称:javascript闭包详解 中文word版 内容简介: Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态语言C/C 的程序员来说是一个新的...
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
### JavaScript闭包完整解释 #### 一、闭包的基本概念 **闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...
标题《JavaScript闭包的理解》涉及的知识点主要围绕JavaScript编程中的一个重要概念——闭包。闭包是一个高级且复杂的话题,它是JavaScript语言的核心特性之一,同时也是一大难点。要想熟练运用JavaScript,掌握闭包...
javascript闭包详解 javascript闭包详解 javascript闭包详解
在深入讨论JavaScript闭包之前,首先需要了解JavaScript的变量作用域。在JavaScript中,变量的作用域分为两种:全局变量和局部变量。全局变量是在函数外部定义的变量,可以在JavaScript程序的任何地方被访问。局部...
JavaScript 闭包是一种高级编程概念,它在JavaScript中扮演着至关重要的角色,特别是在函数式编程和模块化设计中。闭包本质上是函数和其能够访问的变量(包括局部变量)的组合,即使函数已经执行完毕,这些变量仍然...
闭包是ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下...
在JavaScript编程中,闭包是一个核心概念,它允许函数记住并访问所在词法作用域,即使当函数在其词法作用域之外执行时。闭包的特性使得它在JavaScript中既神秘又强大。 首先,我们从闭包的定义谈起。在JavaScript中...
详解JavaScript闭包问题 闭包是纯函数式编程语言的传统特性之一。通过将闭包视为核心语言构件的组成部分,JavaScript语言展示了其与函数式编程语言的紧密联系。由于能够简化复杂的操作,闭包在主流JavaScript库...
### JavaScript闭包技术详解 #### 一、闭包的基本概念 **闭包**是JavaScript中一个重要的概念,它涉及到函数的执行环境、作用域链等关键要素。简单来说,闭包是一个函数及其相关的引用环境的组合。具体而言,当一...
### JavaScript闭包高级教程 #### 简介 在JavaScript编程中,“闭包”是一个非常重要的概念,尤其对于希望深入理解和高效使用JavaScript的开发者来说。简单地说,闭包是一种能够记住并访问其创建时周围环境的函数...
JavaScript中的闭包是一种重要的编程概念,它涉及到函数、作用域和变量持久化。闭包本质上是函数能够记住并访问其词法作用域内的变量,即使该函数已经执行完毕且其外部作用域不再存在。这种特性使得闭包成为...
### JavaScript闭包的理解 #### 一、闭包的定义与特点 闭包是JavaScript中一个非常重要的概念,它指的是一个函数能够访问并操作其外部作用域中的变量的能力。这一特性使得JavaScript具有了一些其他语言不具备的...
JavaScript 闭包是一种强大的特性,它允许函数访问和操作其外部作用域中的变量,即使在外部函数执行完毕后,这些变量仍然保持活动状态。在高级使用中,闭包可以用于实现模块化、数据封装、方法扩展和重载、以及创建...
JavaScript中的闭包是一种高级特性,它允许一个函数访问并操作其外部作用域的变量,即使在外部函数已经执行完毕后。这种机制的核心在于,当内部函数引用了外部函数的变量时,JavaScript会保持对外部作用域的引用,...