JavaScript的变量作用域深入理解


Posted in Javascript onOctober 25, 2009

在学习JavaScript的变量作用域之前,我们应当明确几点:
a、JavaScript的变量作用域是基于其特有的作用域链的。
b、JavaScript没有块级作用域。
c、函数中声明的变量在整个函数中都有定义。

1、JavaScript的作用域链
首先看下下面这段代码:

<script type="text/javascript" language="javascript"> 
var rain = 1; 
function rainman(){ 
var man = 2; 
function inner(){ 
var innerVar = 4; 
alert(rain); 
} 
inner(); //调用inner函数 
} 
rainman(); //调用rainman函数 
</script>

观察alert(rain);这句代码。JavaScript首先在inner函数中查找是否定义了变量rain,如果定义了则使用inner函数中的rain变量;如果inner函数中没有定义rain变量,JavaScript则会继续在rainman函数中查找是否定义了rain变量,在这段代码中rainman函数体内没有定义rain变量,则JavaScript引擎会继续向上(全局对象)查找是否定义了rain;在全局对象中我们定义了rain = 1,因此最终结果会弹出'1'。
作用域链:JavaScript需要查询一个变量x时,首先会查找作用域链的第一个对象,如果以第一个对象没有定义x变量,JavaScript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。
上面的代码涉及到了三个作用域链对象,依次是:inner、rainman、window。

2、函数体内部,局部变量的优先级比同名的全局变量高。

<script type="text/javascript" language="javascript"> 
var rain = 1; //定义全局变量 rain 
function check(){ 
var rain = 100; //定义局部变量rain 
alert( rain ); //这里会弹出 100 
} 
check(); 
alert( rain ); //这里会弹出1 
</script>

3、JavaScript没有块级作用域。
这一点也是JavaScript相比其它语言较灵活的部分。
仔细观察下面的代码,你会发现变量i、j、k作用域是相同的,他们在整个rain函数体内都是全局的。
<script type="text/javascript" language="javascript"> 
function rainman(){ 
/** 
* rainman函数体内存在三个局部变量 i j k 
*/ 
var i = 0; 
if( 1 ){ 
var j = 0; 
for( var k = 0 ; k < 3 ; k++ ){ 
alert( k ); //分别弹出 0 1 2 
} 
alert( k ); //弹出3 
} 
alert( j ); //弹出0 
} 
</script>

4、函数中声明的变量在整个函数中都有定义。
首先观察这段代码。
<script type="text/javascript" language="javascript"> 
function rain(){ 
var x = 1; 
function man(){ 
x = 100; 
} 
man(); //调用man 
alert( x ); //这里会弹出 100 
} 
rain(); //调用rain 
</script>

上面得代码说明了,变量x在整个rain函数体内都可以使用,并可以重新赋值。由于这条规则,会产生“匪夷所思”的结果,观察下面的代码。
这是由于在函数rain内局部变量x在整个函数体内都有定义( var x= 'rain-man',进行了声明),所以在整个rain函数体内隐藏了同名的全局变量x。这里之所以会弹出'undefined'是因为,第一个执行alert(x)时,局部变量x仍未被初始化。
<script type="text/javascript" language="javascript"> 
var x = 1; 
function rain(){ 
alert( x ); //弹出 'undefined',而不是1 
var x = 'rain-man'; 
alert( x ); //弹出 'rain-man' 
} 
rain() 
</script>

所以上面的rain函数等同于下面的函数。
function rain(){ 
var x; 
alert( x ); 
x = 'rain-man'; 
alert( x ); 
}

5、未使用var关键字定义的变量都是全局变量。
<script type="text/javascript" language="javascript"> 
function rain(){ 
x = 100; //声明了全局变量x并进行赋值 
} 
rain(); 
alert( x ); //会弹出100 
</script>

这也是JavaScript新手常见的错误,无意之中留下的许多全局变量。
6、全局变量都是window对象的属性
<script type="text/javascript" language="javascript"> 
var x = 100 ; 
alert( window.x );//弹出100 
alert(x); 
</script>

等同于下面的代码
<script type="text/javascript" language="javascript"> 
window.x = 100; 
alert( window.x ); 
alert(x) 
</script>
Javascript 相关文章推荐
效率高的Javscript字符串替换函数的benchmark
Aug 02 Javascript
Javascript 日期对象Date扩展方法
May 30 Javascript
JS控制TreeView的结点选择
Nov 11 Javascript
十大 Node.js 的 Web 框架(快速提升工作效率)
Jun 30 Javascript
浅谈JS和jQuery的区别
Mar 27 jQuery
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
May 05 Javascript
深入浅析Vue中mixin和extend的区别和使用场景
Aug 01 Javascript
React+Redux实现简单的待办事项列表ToDoList
Sep 29 Javascript
html2canvas属性和使用方法以及如何使用html2canvas将HTML内容写入Canvas生成图片
Jan 12 Javascript
node.js爬虫框架node-crawler初体验
Oct 29 Javascript
javascript实现电商放大镜效果
Nov 23 Javascript
如何利用React实现图片识别App
Feb 18 Javascript
理解JavaScript变量作用域更轻松
Oct 25 #Javascript
理解 JavaScript 预解析
Oct 25 #Javascript
WEB页子窗口(showModalDialog和showModelessDialog)使用说明
Oct 25 #Javascript
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
Oct 25 #Javascript
javascript window对象属性整理
Oct 24 #Javascript
Javascript 模式实例 观察者模式
Oct 24 #Javascript
Jquery 弹出层插件实现代码
Oct 24 #Javascript
You might like
PHP 实例化类的一点摘记
2008/03/23 PHP
写一段简单的PHP建立文件夹代码
2015/01/06 PHP
php微信开发之自定义菜单实现
2016/11/18 PHP
PHP处理Ajax请求与Ajax跨域问题
2017/02/13 PHP
thinkPHP显示不出验证码的原因与解决方法分析
2017/05/20 PHP
ExtJS的FieldSet的column列布局
2009/11/20 Javascript
jQuery中:eq()选择器用法实例
2014/12/29 Javascript
JavaScript比较两个对象是否相等的方法
2015/02/06 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
2015/05/28 Javascript
js钢琴按钮波浪式图片排列效果代码分享
2015/08/26 Javascript
超精准的javascript验证身份证号的具体实现方法
2015/11/18 Javascript
理解javascript正则表达式
2016/03/08 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
用JavaScript实现让浏览器停止载入页面的方法
2017/01/19 Javascript
jQuery+CSS3实现点赞功能
2017/03/13 Javascript
更优雅的微信小程序骨架屏实现详解
2019/08/07 Javascript
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python3.3教程之模拟百度登陆代码分享
2014/01/16 Python
python用户管理系统的实例讲解
2017/12/23 Python
Python使用Matplotlib实现雨点图动画效果的方法
2017/12/23 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
2018/03/04 Python
浅谈Django中的数据库模型类-models.py(一对一的关系)
2018/05/30 Python
python接口自动化测试之接口数据依赖的实现方法
2019/04/26 Python
Python学习笔记之变量、自定义函数用法示例
2019/05/28 Python
解决Python中pandas读取*.csv文件出现编码问题
2019/07/12 Python
解决django model修改添加字段报错的问题
2019/11/18 Python
Python爬虫逆向分析某云音乐加密参数的实例分析
2020/12/04 Python
Python截图并保存的具体实例
2021/01/14 Python
澳大利亚现代波西米亚风格女装网站:Bohemian Traders
2018/04/16 全球购物
竞聘副主任科员演讲稿
2014/01/11 职场文书
社区食品安全实施方案
2014/03/28 职场文书
学院党的群众路线教育实践活动第一阶段情况汇报
2014/10/25 职场文书
2015年煤矿工作总结
2015/04/28 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
2021/05/25 Vue.js