JavaScript 闭包介绍

闭包是JS学习过程中的难点之一,本文主要介绍一下对闭包的认识。

  • JS中变量的作用域;

要理解闭包,先要理解JS中变量的作用域,变量作用域有两种:局部变量和全局变量,JS特殊之处在于,函数内部可以直接读取全局变量。

var name="global";

function foo()
{
   alert(name);
}

foo();

反之,从外部访问函数的局部变量则不行

function foo()
{
   var fun_name = "foo";    // 这里需要注意的是,变量的定位之前如果不加上var的话,fun_name会被作为全局变量对待
}

foo();

fun_name; // undefined
  • 如何从外部读取局部变量;

上面已经介绍过,正常情况下是无法从函数的外部获取到函数内部变量的值的,但是有些情况下这种需求又确实存在,所以需要做一下变通,具体的变通方式请看下面的例子:

function foo()
{
   a=100;
   return function() {return a;}
}
bar=foo();
bar();
  • 闭包的概念;

上面的例子中,函数 foo 内部的匿名函数就是闭包,简单来说,能够读取其他函数内部变量的函数就是闭包,由于在JS中, 只有其他函数内部的子函数才能读取到函数的局部变量,所以可以认为闭包就是子函数。

  • 使用闭包的注意点;

使用必要有两个地方要注意:

1. 闭包会导致函数调用完成后,局部变量仍然不被垃圾回收机制回收,所以可能会导致内存溢出,最好的方法是在变量使用完成后,手动清空不在需要的变量,比如 bar=null;

2. 由于子函数内部可以操作外部函数的局部变量,这个地方要特别注意不要误操作;

  • 思考题;

对比一下两段代码的输出,有助于理解闭包:

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());这断代码中,由于子匿名函数内部并没有定义this指针,所以沿着作用域链向上会找到全局的this指针,全局的this指针对应的name变量的值就是"The Window"
  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());这段代码中,子匿名函数中没有定位that变量,沿着作用域链向上找,找到 getNameFunc 函数,这个函数中定义了 that 变量,that变量的值为指向 object 对象的指针,所以此时 that.name 返回object 对象的name属性。

参考资料:

http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

时间: 2024-11-18 16:24:30

JavaScript 闭包介绍的相关文章

深入理解javascript闭包

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function

javascript闭包详解(内容为转载的,觉得不错就分享一下)

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

浅谈JavaScript闭包

一.背景知识 在介绍闭包之前,我觉得有必要先简单的介绍一些背景知识,如变量的作用域.嵌套函数.垃圾回收机制等概念. 1.作用域 作用域是程序运行时变量可被访问的范围,定义在函数内的的变量是局部变量,局部变量的作用域只能是函数内部范围内,它不能在函数外引用.定义在模块最外层的的变量是全局变量,它是全局范围内可见的,当然在函数里面也可以读取到全局变量的. var a = 123; //全局变量 function fun(){ var b = 456; //局部变量 } 2.嵌套函数 函数不仅可以定义

Javascript闭包!

# javascript闭包(Closure) > 所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 上面是官方的解释,但这解释只会让人头晕.要理解闭包,首先理解两点:变量的作用域以及作用域链,这两个在前面都已经介绍过了,并且举了简单了列子,来回顾一下: var color = "blue";       function changeColor(){              var anotherColo

深入理解JavaScript闭包(closure)

最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目. 一.什么是闭包? “官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话通俗的来说就是:JavaScript中所有的function都是一个

JavaScript闭包其一:闭包概论 函数式编程中一些基本定义

http://www.nowamagic.net/librarys/veda/detail/1707前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了.闭包其实大家都已经谈烂了.尽管如此,这里还是要试着从理论角度来讨论下闭包,看看ECMAScript中的闭包内部究竟是如何工作的. 在直接讨论ECMAScript闭包之前,还是有必要来看一下函数式编程中一些基本定义. 众所周知,在函数式语言中(ECMAScript也支持这种风格),函数即是数据.就比方说,函数可以赋值给变量,可以当参数传递给其他

深入理JavaScript闭包

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function

我对JavaScript闭包的理解

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

用面向对象的Javascript来介绍一下自己

看了一道题目<用面向对象的Javascript来介绍一下自己>,然后自己觉得挺好玩的,所以就编写如下的代码. // HELPER function extend(sup, overrides) { var sub = overrides && overrides.constructor || function() { sup.apply(this, arguments); }; var fn = function() {}; var subp; fn.prototype = n