linux社区爱心援助Linux认证系列教程业界动态站务新闻公司招聘网络学院网址大全LPI专题CISCO专题
设为首页
加入收藏
管理团队
JSP  
JAVA  
PERL  
 您的位置:首页 > 开发语言 > asp.net >
栏目导栏
  php
  JSP
  ASP
  asp.net
  JAVA
  c/c++/c#
  perl
  JavaScript
  Basic
  Delphi
资料搜索
热门文章
·NetBPM工作流的一个示例:请假
·Office Web Components(OWC)绘
·asp.net正则表达式语法
·asp.net 2.0 ajax中使用PopupC
·Ado.Net读取Excel常见问题总结
·数据源为空时如何让GridView显
·如何让UpdatePanel支持文件上传
·C#.Net的常见面试试题和参考答
·asp.net ajax客户端编程+jquer
·Brettle.Web.NeatUpload.dll支
·ASP.NET使用Cookie
·ASP.NET DEMO 15: 同时支持行单
·如何使IE的后退按钮无效
·如何在ASP.NET中用OWC绘制图表
·asp.net:正确判断当前用户角色
最新文章
·Ajax Control Toolkit Animati
·讨论一下类似BlogEngine内一次
·使用CSS+SiteMap+UserControl+
·Asp.net中多彩下拉框的实现
·浅谈ASP.NET的Postback
·分清ASP.NET AJAX中的Extender
·Tip:在使用AjaxControlTookit
·有关注册DataItem的一些可能被
·IIRF(Ionic's Isapi Rewrite
·asp.net 客户端回调功能的实现
·关于控件部分的看法--读Progra
·为什么在vista上做开发
·如何封装JS和CSS文件为服务器端
·岂今我看过的最强的排序算法
·设计模式学习笔记之单件模式
Google
 
ajax-javascript-范围链、call对象与闭包
[ 作者:  加入时间:2007-11-02 13:57:13  来自:Linux联盟收集整理 ]
闭包基础 37RLinux联盟
  都知道,局部变量隐藏全局变量,为什么会隐藏? 37RLinux联盟
   37RLinux联盟
  因为函数对象的[[scope]]内部属性,闭包能实现也因为有这个对象。 37RLinux联盟
   37RLinux联盟
  Excution Context&Scope&Call Object 37RLinux联盟
   37RLinux联盟
  当函数被调用时,解释器为其创建一个上下文,当函数返回时,解释器回到最初的上下文。解释器形成一个上下文栈。上下文包含:全局上下文和局部上下文。 37RLinux联盟
   37RLinux联盟
  创建上下文会伴随一系列对象的创建,包含: 37RLinux联盟
   37RLinux联盟
  Call Object:此对象包含一个arguments属性指向argumets对象。 37RLinux联盟
   37RLinux联盟
  argumentsObject:保含的是调用者指定的参数和被调用函数无关。赋值给Call Object的arguments属性。 37RLinux联盟
   37RLinux联盟
  Scope Object:创建scope对象,并加入scope链,把call Object加入到链头,然后赋值给function object的[[scope]]属性。 37RLinux联盟
   37RLinux联盟
  Variable Object:在此初始化了三种类型的变量:局部变量被初始化为undefined。如果正式的参数(注意不是arguments中的参数)在arguments中有值,用值初始化,否则也初始化为undefined。初始化内部函数。Variable Object指向Call,他们相同。 37RLinux联盟
   37RLinux联盟
  上面是局部上下文,全局上下文比较简单,只包含一个globle对象。别的对象不会被创建,因为没有意义。 37RLinux联盟
   37RLinux联盟
  可以看到只要通过函数对象的[[scope]]内部属性,就能得到函数所需的所有运行信息。 37RLinux联盟
   37RLinux联盟
  注: 37RLinux联盟
   37RLinux联盟
  正式参数:这里指实际参数。 37RLinux联盟
   37RLinux联盟
  上面只是简要说明,只是解释了和闭包有关部分,并不严格,详细的参见ecma-262。 37RLinux联盟
   37RLinux联盟
  Eval&with 37RLinux联盟
   37RLinux联盟
  eval创建新的上下文 37RLinux联盟
   37RLinux联盟
  with会打破现在的上下文 37RLinux联盟
   37RLinux联盟
  闭包 37RLinux联盟
   37RLinux联盟
  在Js中函数嵌套被返回时闭包就形成。因为函数有内置的[[scope]]属性,保持了内层函数的引用,也就保持了整条从内部到globle链的引用。整条链资源不能被释放,当然也能访问链上的变量。 37RLinux联盟
   37RLinux联盟
  解释闭包的例子 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  var x= 5;     //范围globle开始 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  var y=30; 37RLinux联盟
   37RLinux联盟
  function f(y){ //范围f开始 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   return function g()     //范围g开始 37RLinux联盟
   37RLinux联盟
   { 37RLinux联盟
   37RLinux联盟
   var z=10; 37RLinux联盟
   37RLinux联盟
   document.write(x+y+z) 37RLinux联盟
   37RLinux联盟
   } //范围g结束 37RLinux联盟
   37RLinux联盟
  } //范围f结束 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  var f1 = f(5);  输出20 //范围globle结束 37RLinux联盟
   37RLinux联盟
  在g()被执行时,g()的[[scope]]会指向下面的链: 37RLinux联盟
   37RLinux联盟
  首先是g的call object:包含变量z。 37RLinux联盟
   37RLinux联盟
  然后是g的scope对象 37RLinux联盟
   37RLinux联盟
  再后面是f的call objec:包含y 37RLinux联盟
   37RLinux联盟
  再后是f的scop 37RLinux联盟
   37RLinux联盟
  再后是globle object:包含x,y 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  因此执行时,由于g存活,整条链就可以使用,闭包得以形成。变量定位也从当前call object开始,会隐藏同名的y(参数y隐藏全局y)。 37RLinux联盟
   37RLinux联盟
  另一种隐藏是prototype chain,虽然都隐藏变量,但他们完全不同,也没有任何关系,详细见,上一篇继承。 37RLinux联盟
   37RLinux联盟
  MicrosoftAjax.js中的闭包 37RLinux联盟
  createCallback& createDelegate 37RLinux联盟
   37RLinux联盟
  事件不用闭包的实现方式: 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 37RLinux联盟
   37RLinux联盟
  <html xmlns="http://www.w3.org/1999/xhtml" > 37RLinux联盟
   37RLinux联盟
  <head> 37RLinux联盟
   37RLinux联盟
   <title>Untitled Page</title> 37RLinux联盟
   37RLinux联盟
  </head> 37RLinux联盟
   37RLinux联盟
  <body> 37RLinux联盟
   37RLinux联盟
  <input type="button" id="Submit1" value="Test Closure" /> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  <script type="text/javascript"> 37RLinux联盟
   37RLinux联盟
   function TestC(buttonId, message) 37RLinux联盟
   37RLinux联盟
   { 37RLinux联盟
   37RLinux联盟
   this._message = message; 37RLinux联盟
   37RLinux联盟
   var btn = document.getElementById(buttonId); 37RLinux联盟
   37RLinux联盟
   btn.onclick = function(){m.showMessage()} 37RLinux联盟
   37RLinux联盟
   } 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   TestC.prototype.showMessage = function() 37RLinux联盟
   37RLinux联盟
   { 37RLinux联盟
   37RLinux联盟
   alert(this._message); 37RLinux联盟
   37RLinux联盟
   } 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   var m = new TestC('Submit1', 'aaaa'); 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  </script> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  </body> 37RLinux联盟
   37RLinux联盟
  </html> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  下面的语句定死了函数: 37RLinux联盟
   37RLinux联盟
   btn.onclick = function(){m.showMessage()} 37RLinux联盟
   37RLinux联盟
  但是如果用btn.onclick=this.showMessage;由于this指向button,代码又没有办法工作。 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  只能借助闭包和Apply: 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 37RLinux联盟
   37RLinux联盟
  <html xmlns="http://www.w3.org/1999/xhtml" > 37RLinux联盟
   37RLinux联盟
  <head> 37RLinux联盟
   37RLinux联盟
   <title>Untitled Page</title> 37RLinux联盟
   37RLinux联盟
  </head> 37RLinux联盟
   37RLinux联盟
  <body> 37RLinux联盟
   37RLinux联盟
  <input type="button" id="Submit1" value="Test Closure" /> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  <script type="text/javascript"> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   var createDelegate= function Function$createDelegate(instance, method) { 37RLinux联盟
   37RLinux联盟
   /// <param name="instance" mayBeNull="true"></param> 37RLinux联盟
   37RLinux联盟
   /// <param name="method" type="Function"></param> 37RLinux联盟
   37RLinux联盟
   /// <returns type="Function"></returns> 37RLinux联盟
   37RLinux联盟
   return function() { 37RLinux联盟
   37RLinux联盟
   return method.apply(instance, arguments); 37RLinux联盟
   37RLinux联盟
   } 37RLinux联盟
   37RLinux联盟
  } 37RLinux联盟
   37RLinux联盟
   function TestC(buttonId, message) 37RLinux联盟
   37RLinux联盟
   { 37RLinux联盟
   37RLinux联盟
   this._message = message; 37RLinux联盟
   37RLinux联盟
   var btn = document.getElementById(buttonId); 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   btn.onclick=this.showMessage; 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   } 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   TestC.prototype.showMessage = function() 37RLinux联盟
   37RLinux联盟
   { 37RLinux联盟
   37RLinux联盟
   alert(this._message); 37RLinux联盟
   37RLinux联盟
   } 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   var m = new TestC('Submit1', 'aaaa'); 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  </script> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  </body> 37RLinux联盟
   37RLinux联盟
  </html> 37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
   37RLinux联盟
  更多闭包例子 37RLinux联盟
   37RLinux联盟
  下面文中有很多闭包例子,可以在页面执行,看到效果,可以直观感受下什么是闭包 37RLinux联盟
   37RLinux联盟
  http://www.javascriptkit.com/javatutors/closures.shtml 37RLinux联盟
   37RLinux联盟
  看看最新的JS调试器: 37RLinux联盟
  http://weblogs.asp.net/scottgu/archive/2007/07/19/vs-2008-javascript-debugging.aspx 37RLinux联盟
  总的介绍 37RLinux联盟
  http://www.cnblogs.com/bluewater/archive/2007/07/17/821471.html 37RLinux联盟
  namespace 37RLinux联盟
  http://www.cnblogs.com/bluewater/archive/2007/07/18/822485.html 37RLinux联盟
  继承 37RLinux联盟
  http://www.cnblogs.com/bluewater/archive/2007/07/19/823815.html 37RLinux联盟
   37RLinux联盟
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
无相关信息