`
该用户名已经存在
  • 浏览: 307817 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Javascript 中的返回函数和闭包

阅读更多
在Javascript中没有类的概念,函数就是第一类对象。
函数就是对象,主要的表现形式有:
1. 函数可以在运行时创建,也可以在运行的过程中创建。
2. 函数可以被分配给其他变量,可以将它们的引用复制给其他变量。
3. 函数可以作为参数传递给其他函数,且还可以作为其他函数的返回值返回。
4. 函数可以有自己的属性和方法。
本文将重点讨论函数作为返回值的形式。
例如:
    var  setup = function()
    {
        //函数setup的私有变量
         var count = 0;
        //返回函数访问私有变量
         return function()
        {
            return (count += 1);
        };
    };
        //外部调用返回函数
         var next = setup();
        alert(next()); //1
        alert(next()); //2
        alert(next()); //3
        alert(next()); //4

通过以上代码,可以看到2个现象:
1. 变量count是函数setup的私有变量,外部函数是无法直接访问的,但是我们可以通过函数setup的内部匿名函数访问。如果我们将这个内部函数返回,外部调用该函数的时候就可以间接访问函数setup的私有变量。
2. 函数setup的私有变量count看起来像一个静态变量,每次调用都可以在上一次调用的基础上递增1。


现象1:在Javascript中,函数有两个特别的特征,一是前面说过的函数就是对象,二是函数提供局部作用域。这和Java中{}提供变量作用域是有区别的。
Javascript中的作用域链访问模式:
 
    //全局作用域
    var global = "global";

    function outer()
    {
        //函数outer的作用域
        var outer_v = "outer";
       alert(global); //global,能访问全局作用域的变量
        alert(inner); //undefined,不能访问内部函数作用域的变量
        
        var inner = function()
        {
            //函数inner的作用域
              var inner_v = "inner";
            alert(outer_v); //outer,能访问外部函数作用域的变量
        }
    }

    alert(outer_v); //undefined, 不能访问oute函数作用域的变量。

以上代码就是为了说明Javascript语言特有的“链式作用域”结构(chain scope)。即子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。


现象2:为什么函数setup的私有变量count的表现好似Java中的静态变量?
     var next = setup();

不难理解,这句话调用之后,我们创建了一个全局变量next指向了函数setup的内部函数,所以setup的内部函数将一直存在于内存中,不会被垃圾回收器回收。而内部函数的存在是依赖外部函数setup的,所以setup也会一直存在于内存中而不被销毁。所以其私有属性的值不会被重置。特别注意,Javascript中函数不是类,是第一类对象,归根结底是对象,相当于内存中存在一个不被销毁的对象,所以该对象的属性不会被改变,这和Java中的静态变量是有区别的。
可以看出,随意使用返回函数是很消耗性能的,因为这些函数对象将一直存在于内存中。

其实以上阐述的这种返回函数的模式,就是Javascript中所谓的闭包。
闭包的概念:
官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
我的理解是,闭包就是在函数外部使用函数内部的返回函数。
也就是说:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

闭包的作用主要就是为了保护私有变量。
使用闭包的注意事项:
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
2.由于Javascript特殊的作用域链,闭包会在父函数外部,改变父函数内部变量的值。
分享到:
评论

相关推荐

    JavaScript 匿名函数和闭包介绍

    在讨论JavaScript编程语言时,匿名函数和闭包是两个重要的概念,它们在函数式编程和模块化代码设计中扮演着核心角色。匿名函数是没有具体名称的函数,它们可以是独立的,也可以是表达式的一部分,通常用于定义临时...

    深度探讨javascript函数的原型链和闭包

    理解函数的原型链和闭包对于深入掌握JavaScript至关重要。 首先,让我们看看函数的定义方式。在JavaScript中,我们可以使用`function`关键字直接定义函数,如`function fn(a, b) {}`。此外,函数也可以通过赋值语句...

    JavaScript基础篇(6)之函数表达式闭包

    ### JavaScript基础知识点概述 #### 一、函数表达式与函数声明 JavaScript中定义函数主要分为函数声明和函数...通过理解这些基础知识点,可以更好地运用JavaScript中的函数表达式和闭包来编写高效、可维护的代码。

    JavaScript闭包函数

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

    浅析javascript语言中的函数闭包现象.pdf

    JavaScript中的函数闭包是一个重要的概念,它涉及到函数的作用域、变量持久化以及内存管理等多个方面。闭包的本质是在函数内部创建另一个函数,使得内部函数能够访问并操作外部函数的局部变量,即使外部函数已经执行...

    javascript笔记之匿名函数和闭包.docx

    在闭包中,`this`的指向取决于调用上下文。在上述的`getUserFunction`示例中,`this`在闭包内指向的是`window`,而不是`obj`,因为闭包不是一个对象的方法。如果想让`this`指向`obj`,可以使用`.call`或`.apply`方法...

    JS匿名函数、闭包

    **匿名函数**和**闭包**都是JavaScript中非常强大的特性。通过灵活运用这些概念,可以编写出更加高效和可维护的代码。然而,需要注意的是,由于闭包会导致函数的作用域被持续保留,因此过度使用闭包可能会导致内存...

    (转载)JavaScript中匿名函数,函数直接量和闭包.docx

    在JavaScript中,匿名函数、函数直接量和闭包是三种非常重要的概念,它们在编程实践中有着广泛的应用。让我们逐一深入探讨这些概念。 1. **匿名函数**: 匿名函数是指没有名字的函数,通常作为表达式的一部分存在...

    谈谈JavaScript中的函数与闭包

    JavaScript中的函数和闭包是其核心特性之一,它们在编程中扮演着至关重要的角色。首先,我们要理解函数在JavaScript中的地位。JavaScript是一种基于原型的动态类型语言,它允许函数成为一等公民,也就是说,函数可以...

    javascript指南和函数式编程

    而《JavaScript函数式.zip》可能是一份关于JavaScript函数式编程的资料集合,函数式编程是一种编程范式,强调使用函数和避免改变状态。其中可能涵盖以下知识点: 1. **纯函数**:理解纯函数的定义,即给定相同的...

    js高级函数之闭包

    js高级中的函数之闭包函数全解与应用场景(循环闭包,定时器,面试题)

    javascript笔记之匿名函数和闭包

    JavaScript中的匿名函数和闭包是两个非常重要的概念,它们在函数式编程和模块化开发中起着关键作用。 首先,让我们来理解匿名函数。匿名函数,顾名思义,是没有名称的函数。在JavaScript中,我们可以直接定义一个不...

    深入理解javascript原型和闭包

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

    JavaScript 中的闭包是指内部函数可以访问外部函数作用域中的变量

    在JavaScript中,闭包(Closure)是一个极其关键的概念,它使得内部函数能够访问到其外部函数的作用域内的变量,即使外部函数已经执行完毕。这一特性是基于JavaScript的函数作用域规则以及函数本身可以作为值进行...

    详解JavaScript匿名函数和闭包

    这意味着闭包可以访问定义时的作用域,即使函数执行完毕之后,闭包中的变量也不会立即销毁,从而可以实现封装私有变量或保持变量状态。 闭包有如下几个特点: 1. 函数内部可以访问外部函数的作用域。 2. 闭包可以...

    JavaScript函数式编程.pdf

    在JavaScript函数式编程中,闭包是一个非常重要的概念。闭包是指有权访问另一个函数作用域中变量的函数。由于JavaScript的作用域链,闭包能够访问到函数定义时的外部变量,即使外部函数已经执行结束。闭包通常用于...

Global site tag (gtag.js) - Google Analytics