`
king_tt
  • 浏览: 2153359 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

javascript闭包

 
阅读更多

 在学习javascript闭包之前,需要先了解一下"作用域链"。

每一段javascript代码都有一个与之关联的作用域链(scope chain),这个作用域链是一个对象列表或者链表,这组对象定义了这段代码"作用域中"的变量。当javascript需要查找变量x的值的时候,它会从链中的第一个对象开始查找,如果这个对象有一个名为x的属性,则会直接使用这个属性的值,如果第一个对象不存在名为x的属性,javascript会继续查找链上的下一个对象。如果第二个对象依然没有名为x的属性,则会继续查找下一个对象,以此类推。如果作用域链上没有任何一个对象含有属性x,那么就认为这段代码的作用域链上不存在x,并最终抛出一个引用错误异常。

  当定义一个函数的时候,它实际上保存了一个作用域链,当调用这个函数的时候,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的那个作用域链上,同时创建一个新的更长的表示函数调用作用域的"链"。

  函数对象可以通过作用域链关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性就称为"闭包"。也可以这样理解闭包,函数变量可以被隐藏于作用域链之内,看起来是函数将变量"包裹"了起来。

  概念说了一堆,来个示例可能会比较清晰。

  var a = 1;

  function testFun(){

    var a = 10;

    function tempFun(){return a;}

    return tempFun();    

  }

  testFun();

  上述例子执行的结果是返回10。

  对于上述例子,我们来做一下改动。

  var a = 1;

  function testFun(){

    var a = 10;

    function tempFun(){return a;}

    return tempFun;

  }

  testFun()();

  对于这个例子,很多人会下意识的认为返回结果为1,理由就是函数tempFun是在全局环境下执行的,因此会返回1。然而结果是返回10。

  由于javascript函数的执行用到了作用域链,这个作用域链是函数定义的时候创建的。

  嵌套的函数tempFun定义在这个作用域链里,其中的变量a是局部变量,不管在什么时候执行函数tempFun,这种绑定在执行tempFun依然有效,因此结果返回10而不是1。

  这里我们可以看到闭包的强大之处:它们可以捕捉到局部变量(参数),并一直保存下来,看起来像这些变量绑定到了在其中定义它们的外部函数。

众所周知,javascript没有块级作用域,只有函数作用域。那就意味着定义在函数中的参数和变量在函数外部是不可见的,而在一个函数内部任何位置定义的变量,在该函数内部任何地方都可见。这带来的好处是内部函数可以访问定义它们的外部函数的参数和变量

首先,我们来构造一个简单的对象

复制代码
 1 var testObj = {
 2     value: 10,
 3     add: function(inc){
 4         this.value += (typeof inc === "number") ? inc : 1;
 5     }
 6 };
 7 
 8 testObj.add();
 9 testObj.value;    // 11
10 
11 testObj.add(2);    
12 testObj.value;    // 13
复制代码

这样写就有一个问题,value值不能保证不会被非法修改,可以按如下的方法进行修改。

复制代码
 1 var testObj = (function(){
 2     var value = 10;
 3     return {
 4         add: function(inc){
 5             value += (typeof inc === "number") ? inc : 1;
 6         },
 7         getValue: function(){
 8             return value;
 9         }
10     };
11 })();
12 
13 testObj.add();
14 testObj.getValue();    // 11
15 
16 testObj.add(2);
17 testObj.getValue(); // 13
复制代码

我们可以通用调用一个函数的形式去初始化testObj,该函数会返回一个对象字面量,函数里定义了一个value变量,该变量对add和getValue方法总是可用的,但函数的作用域使得它对其他的程序来说是不可见的。同时,我们还可以得出一个结论,内部函数拥有比它的外部函数更长的生命周期。

我们再继续看一个构造函数调用的例子。

复制代码
var MyObj = function(str){
    this.status = str;
};

MyObj.prototype.getStatus = function(){
    return this.status;
};

var obj = new MyObj("javascript");
obj.getStatus(); // "javascript"
复制代码

这样写并没有错,但是会有一点“多此一举”,为什么要用一个getStatus方法去访问一个本可以直接访问到的属性呢?如果status是私有属性,那当然才有意义。

复制代码
var obj = function(status){
    return {
        getStatus: function(){
            return status;
        }
    };
};

var myObj = obj("javascript");
myObj.getStatus(); // "javascript"
复制代码

这里当我们调用obj的时候,它返回包含getStatus方法的一个新对象,该对象的一个引用保存在myObj中,即使obj已经返回了,但getStatus方法仍然享有访问obj对象的status属性的特权。getStatus方法并不是访问该参数的一个副本,它访问的就是该参数本身。这是可能的,因为该函数可以访问它被创建时所处的上下文环境,这被称为闭包

分享到:
评论

相关推荐

    JavaScript闭包

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

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

    JavaScript 闭包研究及典型应用 JavaScript 闭包是一种强大的技术,能够在各种场景中发挥重要作用。本文将介绍 JavaScript 闭包的定义、使用场景和典型应用。 闭包函数的定义和使用场景 在 JavaScript 语言中,...

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

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

    javascript 闭包

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

    javascript闭包详解中文word版

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

    尚硅谷——JavaScript闭包

    JavaScript闭包 JavaScript闭包 JavaScript闭包 JavaScript闭包

    Javascript 闭包完整解释

    Javascript 闭包完整解释

    javascript 闭包实例下载

    JavaScript 闭包是一种高级编程概念,它在JavaScript中扮演着至关重要的角色,特别是在函数式编程和模块化设计中。闭包本质上是函数和其能够访问...通过学习这些实例,你将能够更好地掌握JavaScript闭包这一核心概念。

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

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

    javaScript闭包技术资料

    javaScript闭包技术资料

    JavaScript闭包(closure).pdf

    理解并掌握JavaScript闭包是成为专业前端开发者的关键一步。在实际开发中,合理利用闭包可以提高代码的复用性和可维护性,同时也能避免一些常见的编程陷阱。通过深入学习和实践,可以更好地运用闭包这一强大的工具来...

    javascript闭包高级教程

    javascript闭包高级教程,闭包内部实现机制的完美展现,值得研究,比较难。

    揭开Javascript闭包的真实面目

    【JavaScript 闭包详解】 闭包是JavaScript编程中一个核心且关键的概念,尤其对于初学者而言,理解起来可能有些挑战。闭包本质上是一种特殊的作用域,它可以捕获并存储其外部函数作用域内的变量,即使外部函数已经...

    javascript闭包的高级使用方法实例

    介绍了javascript闭包的高级使用方法实例,有需要的朋友可以参考一下

    javaScript闭包

    javaScript闭包技术资料。javaScript闭包技术资料。

    javascript闭包详解

    javascript闭包详解 javascript闭包详解 javascript闭包详解

    JavaScript闭包的定义和理解,含代码示例

    JavaScript闭包的定义和理解,含代码示例

    JavaScript闭包技术及IE内存泄漏分析.pdf

    JavaScript闭包技术及IE内存泄漏分析

Global site tag (gtag.js) - Google Analytics