`
fengqx
  • 浏览: 99176 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

js闭包问题

阅读更多
什么是闭包(closures)
闭包就是内部函数通过某种方式使其可见范围超出了其定义的范围,这就产生了一个在其定义范围内的闭包.
一 、内部函数(inner function)
javascript是支持内部函数申明(inner function declaration)的编程语言,

内部函数就是在另一个函数的内部定义,如
function outerFun(){
  function innerFun(){
    alert('hello');
  }
}

函数innerFun就是内部函数, 它在函数outerFun范围内是可见的,
也就是说innerFun函数的命名空间(namespace)是在outerFun范围之内.

正确调用
function outerFun(){
  function innerFun(){
    alert('hello');
  }
  innerFun();
}
outerFun(); alerts hello
错误调用(error)
function outerFun(){
  function innerFun(){
    alert('hello');
  }
}
innerFun();

那么如果我想在函数outerFun外面调用函数innerFun,我该如何做呢
做法1
var globVar;
function outerFun() {
  function innerFun() {
   alert('hello');
  }
  globVar = innerFun;
}
outerFun();
globVar();
做法2
function outerFun() {
  function innerFun() {
    alert('hello');
  }
  return innerFun ;
}
var globVar = outerFun();
globVar();

做法3
function outerFun() {
  function innerFun() {
    alert('hello');
  }
  return {'innerFun'innerFun} ;
}
var globVar = outerFun();
globVar.innerFun();

以上三种做法把内部函数的可见范围扩大了, 其中最后一种做法是把内部函数当做匿名对象{'innerFun'innerFun}的属性,并随之一起返回.

从中看到在javascript里面,函数名称可以当作是一种引用变量,类似于c里面指针的概念,在这里,随着程序的执行
会产生两个引用变量指向内部函数innerFun,一个是globVar(第三种做法是globVar.innerFun),另一个是其函数自身innerFun,
只不过这两个变量的可见范围不一样,即命名空间不一样.
javascript垃圾回收器会在函数最后一个引用变量被废弃后,释放其所占用的内存.


二 变量范围
例1 内部函数变量
在内部函数内申明的变量其可见范围就在其函数内
function outerFun() {
   function innerFun() {
      var innerVar = 0;
      innerVar++;
      alert(innerVar);
   }
   return innerFun;
}
var globVar = outerFun();
globVar();  Alerts 1
globVar();  Alerts 1
var innerVar2 = outerFun();
innerVar2();  Alerts 1
innerVar2();  Alerts 1

每一次内部函数调用,一个新的innerVar变量都被创建,所以结果显示都是1


例2 内部函数引用全局变量(global variables)

var globVar = 0;
function outerFun() {
  function innerFun() {
    globVar++;
    alert(globVar);
  }
  return innerFun;
}
var globVar = outerFun();
globVar();  Alerts 1
globVar();  Alerts 2
var globVar2 = outerFun();
globVar2();  Alerts 3
globVar2();  Alerts 4
每一次内部函数的调用,全局变量都增加1,所以显示结果都是依次递增.

例3 内部函数引用外部函数变量
 
  function outerFun() {
     var outerVar = 0;
     function innerFun() {
       outerVar++;
       alert(outerVar);
     }
     return innerFun;
  }
 
  var globVar = outerFun();
  globVar();  Alerts 1
  globVar();  Alerts 2
  var globVar2 = outerFun();
  globVar2();  Alerts 1
  globVar2();  Alerts 2
  注意在第2次调用outerFun()的时候重新创建了一个新的变量outerVar,所以显示结果是1,2,1,2

什么是闭包(closures)呢, 就是内部函数通过某种方式使其可见范围超出了其定义的范围, 如上例3,globVar 就是函数outerFun()的一个闭包,
而闭包产生的时机就是这句代码var globVar = outerFun(); 再看上例3,闭包globVar第一次调用之后,变量outerVar 值 1 还是在内存
中,没有回收,因为闭包globVar第二次调用的时候其值已经递增为2 ,只要globVar没有被废弃掉,则outerVar的值就会一直存在. 像outerVar
这样的变量称其为自由变量

三 闭包与面向对象编程之间的联系
   看看下面的例子
   function outerFun() {
     var outerVar = 0;
     function innerFun() {
     outerVar++;
     alert(outerVar);
     }
     function innerFun2() {
       outerVar = outerVar + 2;
       alert(globVar);
     }
     return {'innerFun' innerFun, 'outerFun2' outerFun2};
   }

   var globVar = outerFun();
   globVar.innerFun();  Alerts 1
   globVar.innerFun2();  Alerts 3
   globVar.innerFun();  Alerts 4
   var globVar2 = outerFun();
   globVar2.innerFun();  Alerts 1
   globVar2.innerFun2();  Alerts 3
   globVar2.innerFun();  Alerts 4
  
   outerFun()可以看成是类,globVar,globVar2可以看成是两个实例,实例变量就是outerVar,并且是private. 函数innerFun(),
   innerFun2()就是实例方法. 
  
   可能这还不是很清楚,在看下面的例子
   function Boy(){
      var name;
      function setName(vName){
        name = vName;
      }
      function getName(){
        return name;
      }
      return {'setName' setName, 'getName' getName};
   }
   var boy1 = Boy();
   boy1.setName(zhuzhenhua);
   alert(boy1.getName());
  
分享到:
评论

相关推荐

    【JavaScript源代码】详解JavaScript闭包问题.docx

    详解JavaScript闭包问题  闭包是纯函数式编程语言的传统特性之一。通过将闭包视为核心语言构件的组成部分,JavaScript语言展示了其与函数式编程语言的紧密联系。由于能够简化复杂的操作,闭包在主流JavaScript库...

    JS闭包可被利用的常见场景

    JavaScript 闭包是一种强大的编程工具,常常被用来解决特定的问题和优化代码结构。在JavaScript中,闭包是指一个函数能够访问并操作其定义时的作用域内的变量,即使该函数在其外部作用域被调用。以下将详细介绍两个...

    js闭包个人理解

    ### JavaScript闭包的理解 在JavaScript中,闭包(Closure)是一种非常重要的概念,它涉及到函数作用域、变量生命周期以及函数内部对外部作用域的访问等多个方面。本文将基于提供的文件内容,深入探讨JavaScript...

    Javascript 闭包完整解释

    ### JavaScript闭包完整解释 #### 一、闭包的基本概念 **闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...

    js闭包详细讲解

    ### JavaScript闭包详解 #### 一、闭包概念与特性 **闭包**是JavaScript语言的一个重要特性,它使得函数可以访问并操作其外部作用域内的变量,即使该函数在其外部作用域之外被调用。要理解闭包,首先需要了解...

    js闭包写法学习demo

    以下是一些关于JavaScript闭包的关键知识点: 1. **函数嵌套**:闭包最常见的形式是内部函数引用了外部函数的变量。例如: ```javascript function outerFunction() { var outerVar = 'I am from the outer ...

    js闭包理解之倒计时

    在这个“js闭包理解之倒计时”的主题中,我们将深入探讨如何利用闭包实现一个实际项目中的倒计时功能。 首先,让我们了解一下闭包的基本概念。在JavaScript中,每当函数被创建时,它都会形成一个闭包,这个闭包包含...

    js闭包学习

    JavaScript中的闭包是一种强大的特性,它允许函数访问和操作其外部作用域内的变量,即使在外部函数执行完毕后,闭包依然能保持对外部变量的访问。闭包的关键在于,它能够保留函数内部状态,使得数据得以持久化,这...

    JavaScript闭包

    Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态...本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。

    JavaScript闭包研究及典型应用.pdf

    JavaScript 闭包研究及典型应用 JavaScript 闭包是一种强大的技术,能够在各种场景中发挥重要作用...正确使用 JavaScript 闭包函数可以提高代码的可读性和可维护性,但是如果使用不当,可能会导致浏览器内存泄露问题。

    JS 闭包的理解

    总之,JavaScript闭包是理解和编写高效、模块化代码的关键概念,它能帮助我们更好地管理作用域、变量和内存,从而提高代码的复用性和可维护性。在日常开发中,熟练掌握闭包不仅可以提升编程技能,也能让代码更加优雅...

    js闭包的理解以及作用.docx

    闭包是JavaScript中实现数据隐藏和封装的一种重要手段,对于理解和编写高效的JS代码至关重要。 1. **作用域的理解** - **全局变量**:在整个程序中都可访问的变量,它们在整个脚本的生命周期内都存在。 - **局部...

    JS闭包经典

    闭包一点即通 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

    javascript 闭包

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

    JavaScript闭包函数

    闭包是ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下...

    基于JavaScript闭包的Web图片浏览控件的实现.pdf

    基于JavaScript闭包的Web图片浏览控件的实现 本文主要讲解了基于JavaScript闭包原理的Web图片浏览控件的实现,包括JavaScript闭包概念、闭包应用场景、Web图片浏览控件的设计思路和实现方法。 1. JavaScript闭包...

    深入理解javascript原型和闭包

    深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系

    javascript闭包详解中文word版

    资源名称:javascript闭包详解 中文word版   内容简介: Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态语言C/C 的程序员来说是一个新的...

    浅谈js 闭包引起的内存泄露问题

    在JavaScript编程中,闭包是一个非常重要的概念,它的特性使得函数可以访问到外部函数作用域中的变量。然而,闭包如果使用不当,非常容易引起...通过以上措施,可以最大限度地减少JavaScript闭包所带来的内存泄漏问题。

Global site tag (gtag.js) - Google Analytics