PHP知识、源码、教程、框架、程序分享! -- PHP社区 关于我们 联系我们 联系电话 联系QQ

JavaScript语法中常见陷阱,作用域解析和闭包

发表时间:2013-08-27 点击:

[本文摘要]:JavaScript语法 中常见陷阱,作用域解析和闭包 因为后续文章将会详细讨论JavaScript的对象模型,所以这里只简单介绍一下作用域和闭包的问题。 首先,我们看作用域。作用域是指对某一...

JavaScript语法中常见陷阱,作用域解析和闭包

因为后续文章将会详细讨论JavaScript的对象模型,所以这里只简单介绍一下作用域和闭包的问题。

首先,我们看作用域。作用域是指对某一属性(变量)或方法(函数)具有访问权限的代码空间。在JavaScript中,作用域是在函数中进行维护的,即在下面这个函数中

	function myFunction() {
	    var myVariable = 'inside';
	  }

变量myVariable的作用域会被限制在myFunction()中。如果你在这个函数之外访问myVariable,结果将是无效的:

	  function myFunction() {
	    var myVariable = 'inside';
	  }
	  myFunction();
	  alert(myVariable);

同样地,在这种情况下执行这个函数不会影响到外部作用域:

	  function myFunction() {
	    var myVariable = 'inside';
	  }
	  //  定义变量
	  var myVariable = 'outside';
	  //  执行前面的函数
	  myFunction();
	  alert(myVariable); //  将提示"outside"

在这个例子中,因为在函数内部使用了var关键字来维护作用域链,所以执行myFunction()函数对位于其外部作用域中的myVariable没有影响。如果在myFunction()内部去掉为myVari-able赋值时使用的var关键字,那么myVariable的作用域将会解析到myFunction()的外部,因此就会修改外部的变量:

	  function myFunction() {
	    //  没有使用var
	    myVariable = 'inside';
	  }
	  //  定义变量
	  var myVariable = 'outside';
	  //  执行函数
	  myFunction();
	  alert(myVariable); //  将提示"inside"

作用域链是用来描述一种路径的术语,沿着该路径可以确定变量的值(或者当函数被调用时要使用的方法)。当给myVariable赋"inside"值时,myFunction()的作用域中没有使用var关键字,因此赋值操作会沿着作用域链查找到执行myFunction()的作用域中(在这种情况下是window对象内部),并修改其中myVariable实例的值。从本质上说,var关键字决定了哪个函数是特定变量的作用域链的终点。同样的逻辑也适用于取得变量值的情况。

除了var关键字之外,像下面这样将变量包含在定义函数时的圆括号内,与使用var关键字的效果是相同的,即该变量也会被包含在函数的作用域内:function myFunction (myVariable) { ... }

闭包是与作用域相关的一个概念,它指的是内部函数即使在外部函数执行完成并终止以后,仍然可以访问其外部函数的属性。当引用一个变量或方法时,JavaScript会沿着由对象执行路径构成的作用域链对作用域进行解析,查找变量最近定义的值,一旦找到,即使用该值。

作用域解析和闭包中的隐含问题往往并不是一开始就显而易见的,而且通常是我遇到过的"残缺(broken)"脚本中大部分问题的根源所在。为了说明这一点,我们来看下面的例子:

	   function initAnchors(W3CEvent) {
	     for (var i=1 ; i<=3 ; i++ ) {
	       var anchor = document.getElementById('anchor' + i);
	       ADS.addEvent(anchor,'click',function() {
	        alert('My id is anchor' + i);
	       });
	     }
	   });
	   ADS.addEvent(window, 'load', initAnchors);

这个例子通过在窗口载入完成时运行initAnchors()函数,为页面中的锚注册事件侦听器。现在,我们假设文档中有3个锚元素,它们的ID值分别为anchor1到anchor3,那么单击这几个锚的结果会怎样呢?你可以自己试一下,打开下载源文件中的chapter/scopechain/example1.html,并单击其中的几个锚。

虽然代码中的语法正确,但其中的逻辑却存在缺陷。大多数新手,甚至某些经验丰富的程序员,都会设想当单击每个锚时,会提示My id is anchorX(其中X对应着指定click事件侦听器时i的值)。如果真是这样,单击第一个锚应该提示My id is anchor1,而单击第三个应该提示My id is anchor3。但这种设想是错的。事实上单击每个锚都会提示相同的信息,如图1-4所示。


图1-4    警告窗口中显示了单击后的实际结果

版权声明:本文系技术人员研究整理的智慧结晶,转载勿用于商业用途,并保留本文链接,侵权必究!

本文链接:http://php.aixc.cn/web/js/52.html

声明:本站技术及源码均为原创,转载请勿用于商业用途,并注明出处及原文链接,侵权必究。