Javascript的闭包

简介
Closure
所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
闭包是 ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下。如果想要扬长避短地使用闭包这一特性,则必须了解它们的工作机制。而闭包工作机制的实现很大程度上有赖于标识符(或者说对象属性)解析过程中作用域的角色。

关于闭包,最简单的描述就是 ECMAScript 允许使用内部函数--即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。

遗憾的是,要适当地理解闭包就必须理解闭包背后运行的机制,以及许多相关的技术细节。虽然本文的前半部分并没有涉及 ECMA 262 规范指定的某些算法,但仍然有许多无法回避或简化的内容。对于个别熟悉对象属性名解析的人来说,可以跳过相关的内容,但是除非你对闭包也非常熟悉,否则最好是不要跳过下面几节。

对象属性名解析
ECMAScript 认可两类对象:原生(Native)对象和宿主(Host)对象,其中宿主对象包含一个被称为内置对象的原生对象的子类(ECMA 262 3rd Ed Section 4.3)。原生对象属于语言,而宿主对象由环境提供,比如说可能是文档对象、DOM 等类似的对象。

原生对象具有松散和动态的命名属性(对于某些实现的内置对象子类别而言,动态性是受限的--但这不是太大的问题)。对象的命名属性用于保存值,该值可以是指向另一个对象(Objects)的引用(在这个意义上说,函数也是对象),也可以是一些基本的数据类型,比如:String、Number、Boolean、Null 或 Undefined。其中比较特殊的是 Undefined 类型,因为可以给对象的属性指定一个 Undefined 类型的值,而不会删除对象的相应属性。而且,该属性只是保存着 undefined 值。

下面简要介绍一下如何设置和读取对象的属性值,并最大程度地体现相应的内部细节。

值的赋予
对象的命名属性可以通过为该命名属性赋值来创建,或重新赋值。即,对于:

var objectRef = new Object(); //创建一个普通的 javascript 对象。
可以通过下面语句来创建名为 “testNumber” 的属性:

objectRef.testNumber = 5;
/* - 或- */
objectRef["testNumber"] = 5;
在赋值之前,对象中没有“testNumber” 属性,但在赋值后,则创建一个属性。之后的任何赋值语句都不需要再创建这个属性,而只会重新设置它的值:

objectRef.testNumber = 8;
/* - 或- */
objectRef["testNumber"] = 8;
稍后我们会介绍,Javascript 对象都有原型(prototypes)属性,而这些原型本身也是对象,因而也可以带有命名的属性。但是,原型对象命名属性的作用并不体现在赋值阶段。同样,在将值赋给其命名属性时,如果对象没有该属性则会创建该命名属性,否则会重设该属性的值。

更详细的请查看下面的文章:
http://demo.jb51.net/js/javascript_bibao/index.htm

(0)

相关推荐

  • JavaScript中通过闭包解决只能取得包含函数中任何变量最后一个值的问题

    复制代码 代码如下: <script type="text/javascript"> function createArray() { var arr = new Array(); for (var i = 0; i < 10; i++) { arr[i] = function () { return i; } } return arr; } var funcs = createArray(); for (var i = 0; i < funcs.length;

  • javascript 闭包函数做显隐内容

    New Document .a{ width:200px; font-size:12px; font-weight:bold; height:30px; line-height:30px; background:url(/images/default/header_bg.gif); margin-top:5px; } .a a{ text-Decoration:none;} .aa{ width:200px; height:100px; border:3px groove #91D2FF; di

  • javascript 常见的闭包问题的解决办法

    0 1 2 3 4 5 6 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 上段代码本意是在每个div上都加一个事件,即每当点击div时,就显示此div的相应序号.但是运行程序时我们会发现,不论点击那个,只会显示7,这是什么愿因呢.--这就是闭包的问题 原来 在js中,函数中在定义函数,就出现闭包了.此时外层函数中变量是可以在里层函数里利用的,即使外层函数结束.但是当外层中出现循环的时候,如果在里层函数中利用这个循环变量的话,会直接引用这个变量的最终值. 就像上述代码演示的一样. 如

  • javascript 闭包疑问

    复制代码 代码如下: var test=(function() { var arr2=[1,2,3,3]; return function(){ return arr2; }; })() Array.prototype.f1= function () { return []; } Array.prototype.f2= function () { this.length=0; return this; } 然后用两种方式调用: 一:var arr= test(); console.log(arr

  • JavaScript中的闭包原理分析

    我们来看一个定义: Closure 所谓"闭包",指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 这说明了,JavaScript中的闭包是包含了上下文的函数,也就是说,这个函数的作用基础,是它所处的环境,这是不能超越的,跟线性代数是不是有一点似曾相识的感觉呢? 换个角度看,闭包的作用是为了实现OO.JavaScript中,没有像C++那样的public.private.protect属性标识, 建立起类比较困难."类

  • JavaScript 闭包在封装函数时的简单分析

    wbkt2t最近发现了一个新名词:闭包.(自己落后了,要好好学习才行),baidu.google看了一下原理和实例,也明白了闭包的强大.JQuery也把闭包发扬光大了,网上一些个人开发的框架都是用了闭包了功能.知道了闭包的原理和使用发放,于是自己小小试验了一把,带着疑惑:使用闭包有什么好处?不使用会出现什么后果?写下了以下代码,也希望大家给小弟一些解答 使用闭包: 实例1 复制代码 代码如下: var $Darren; (function(){ var Obj={version:"1.0&quo

  • javascript 闭包

    对于初学者来说,理解Javascript闭包(closure)还是比较困难的,而撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目,让初学者理解起来更加容易一些. 一.什么是闭包? "官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术. 其实这句话通俗的来说就是:JavaScript中所有的function都是一个闭包.不过一般来说,嵌套的func

  • javascript深入理解js闭包

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

  • Javascript闭包演示代码小结

    闭包演示 p {background:gold;} function init() { var pAry = document.getElementsByTagName("p"); for( var i=0; i 产品 0 产品 1 产品 2 产品 3 产品 4 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 以上场景是初学者经常碰到的.即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索

  • 浅析javascript闭包 实例分析

    官方解释 "闭包"是一个拥有许多变量和绑定了这些变量的环境表达式(通常是一个函数),因而这些变量也是环境表达式的一部分. 通俗解释 Javascript中所有的函数都是一个闭包.不过一般来说,嵌套的function产生的闭包更为强大,也是大部分时候我们所说的"闭包".看如下代码: 复制代码 代码如下: <script type="text/javascript"> <!-- //外层函数a function a(){ //临时变

  • javascript,jquery闭包概念分析

    但javascript我是经常要用,所以是要懂这里面的概念. 其实javascript里的闭包概念很简单,就是函数用到外部变量,不需要传参就可以获取. 举个例子: 复制代码 代码如下: <script> var sMessage = "Hello world"; function sayHello(){ alert(sMessage); } sayHello(); addNumber(1,2); var iBaseNum = 10; function addNumber(i

  • javascript学习之闭包分析

    在ECMAScript中,在函数声明处向函数外部看到的声明的所有变量,在函数内部都能访问到它们的最终值! 闭包函数只能访问变量的最终值!!! eg: function fnTest(arr) {   for (var i=0;i < arr.length;i++) { arr[i]=function () { alert(i+" | "+arr[i]); };   } } var arr = [0,1,2,3]; fnTest(arr); for (var i=0;i <

  • 深入理解Javascript闭包 新手版

    一.什么是闭包? "官方"的解释是:所谓"闭包",指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 相信很少有人能直接看懂这句话,因为他描述的太学术.我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的.看下面这段代码: 复制代码 代码如下: function a(){ var i=0; function b(){ alert(++i); }

  • javascript闭包的理解和实例

    顺便提示一下: 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域. with和eval除外,所以只能说JS的作用域机制非常接近词法作用域(Lexical scope). 下面是一个简单的使用全局变量的闭包实例: 复制代码 代码如下: var sWord="Hello,Welcome to web前端开发工程师的博客,请多多指教." function disWord(){ alert(sWord);

随机推荐