系列文章导航:
Javascript学习笔记九——prototype封装继承
每个写过程序的人都不会对作用域这个概念陌生,那在这篇文章中就来谈下Javascript的作用域。
在Javascript,全局环境本身就一个对象。在浏览器宿主中这个对象是window,而当Javascript用于其它非浏览器的宿主,如嵌入式的环境中,可能会是其它的对象。
在这里也纠正一个观念,有很多人都认为Javascript只在浏览器中使用,其实Javascript也能在很多非Web情况下使用,据介绍Javascript在一些基于嵌入式的应用领域表现得也很出色,当然这些我也只是听过传说而已。
言归正传,当我们写下:var i=1时,其实就是声明了一个window作用域的一个变量。
而当我们写下i=1时,是声明了一个window的属性。
看这样一段代码:
<script type="text/javascript"> var a = "hello"; b = "world"; Test(); function Test() { alert(a + " " + b); var a = "welcome"; b = "china"; alert(a + " " + b); } alert(a + " " + b); script>
这段代码分别输出的结果是:undefined world,welcome china, hello china.
我们来分别解释:
在上文中,我们说过,在Javascript预编译时,会把所有var变量创建,默认值为undefined,我们在这里可以举一个例子:
我们可以写这样一段代码:
<script type="text/javascript"> alert(a); alert(b); var a = "111"; b = "111"; script>
当我们执行运行这段脚本时,可以发现,首先弹出undefined,然后回提示脚本错误,提示b不存在。由此就可以表明,a在预编译的过程中就已经被创建并且初始化为undefined,而b却只能在实际运行时按顺序去解释。其实在预编译后的Javascript代码可以近乎理解如下:
<script type="text/javascript"> var a = undefined; alert(a); alert(b); a = "111"; b = "111"; script>
接下来我们可以谈一下函数的作用域问题,每当代码运行进入一个函数时,Javascript引擎就会自动创建一个新的作用域,然后把这个新作用域作为当前作用域的子作用域,然后把当前的代码作用域切换到这个新作用域。当代码退出函数时,这个作用域销毁,把代码作用域交还给他的父作用域。
好,准备工作差不多了,接下来我们就来解释第一个问题:问什么会输出undefined world。
首先代码进行在预编译,当进入 Test方法时,开启一个新作用域,然后把全局作用域作为他的父作用域。然后对Test内的方法进行预编译,和上面的代码一样,Test方法被预编译后方法体大致如下:
function Test() { var a = undefined; alert(a + " " + b); var a = "welcome"; b = "china"; alert(a + " " + b); }
当然,在当前作用域下无法找到b,于是他就会到他的父作用域下,也就是全局作用域找到了b=“world”。于是也就产生了这样的结果。
第二次弹出welcome china,没什么好说的。
第三次,弹出hello china。我们可以这样理解,var a 只是 方法Test的一个局部变量,而b由于事先未声明,因此他会去父作用域中去找到对应的定义。
好,接下来,我们再看一下这个方法的若干个变体。
<script type="text/javascript"> var a = "hello"; b = "world"; Test(); function Test() { alert(a + " " + b); a = "welcome"; b = "china"; alert(a + " " + b); } alert(a + " " + b); script>
首先,我们将方法体内的var a改成a,我们先不看答案,直接来分析,首先,在预编译阶段,方法体内几乎没有任何改变,因此此时a和b一样,都要去他们的父作用域中去寻找,因此第一次出的结果应该是hello world,第二次没什么说的:welcome china,第三次由于a和b在本作用域内都没有事先定义,因此都是再改变父作用域内的值,因此应该输出welcome china.
我们继续:
<script type="text/javascript"> var a = "hello"; b = "world"; Test(); function Test() { alert(a + " " + b); var a = "welcome"; var b = "china"; alert(a + " " + b); } alert(a + " " + b); script>
和上面的分析一样,应该输出undefined undefined,welcome china,hello world.
继续:
<script type="text/javascript"> a = "hello"; b = "world"; Test(); function Test() { alert(a + " " + b); var a = "welcome"; b = "china"; alert(a + " " + b); } alert(a + " " + b); script>
应该是undefined world,welcome china,hello china.
经试验,都没问题, 不知道你明白了么?
因此我们可以得出,每个变量在找不到自己的定义时,都会沿着作用链向上寻找,这样就很可能会出现未预知的错误,给排错添加了很多困难。更麻烦的是,还可能会对父作用域上的变量值进行修改,因此我们在声明变量时应该尽量加上var,尽管Javascript并不强迫我们这样做。
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容