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 相关文章推荐
jQuery使用手册之二 DOM操作
Mar 24 Javascript
Javascript 学习笔记 错误处理
Jul 30 Javascript
js 时间函数应用加、减、比较、格式转换的示例代码
Aug 23 Javascript
仿百度的关键词匹配搜索示例
Sep 25 Javascript
调用innerHTML之后onclick失效问题的解决方法
Jan 28 Javascript
关于javaScript注册click事件传递参数的不成功问题
Jul 18 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
Apr 23 Javascript
JS基于面向对象实现的拖拽功能示例
Dec 20 Javascript
Linux系统中利用node.js提取Word(doc/docx)及PDF文本的内容
Jun 17 Javascript
React Native实现地址挑选器功能
Oct 24 Javascript
使用Node搭建reactSSR服务端渲染架构
Aug 30 Javascript
基于javascript实现放大镜特效
Dec 03 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魔术方法__GET、__SET使用实例
2014/11/25 PHP
PHP实现动态柱状图改进版
2015/03/30 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
php实现二叉树中和为某一值的路径方法
2018/10/14 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
php apache开启跨域模式过程详解
2019/07/08 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
2014/06/15 Javascript
JS实现控制表格只显示行边框或者只显示列边框的方法
2015/03/31 Javascript
javascript实现确定和取消提示框效果
2015/07/10 Javascript
Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
2016/02/02 Javascript
Vue AST源码解析第一篇
2017/07/19 Javascript
自定义javascript验证框架示例【附源码下载】
2019/05/31 Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
2020/05/01 Javascript
python基础教程之字典操作详解
2014/03/25 Python
Django权限机制实现代码详解
2018/02/05 Python
python: line=f.readlines()消除line中\n的方法
2018/03/19 Python
python中如何使用分步式进程计算详解
2019/03/22 Python
详解Django定时任务模块设计与实践
2019/07/24 Python
Kiwi.com中国:找到特价机票并发现新目的地
2019/10/27 全球购物
三个Unix的命令面试题
2015/04/12 面试题
正规的求职信范文分享
2013/12/11 职场文书
班组长工作职责
2013/12/25 职场文书
幼儿园中班评语大全
2014/04/17 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
119消防日活动总结
2014/08/29 职场文书
2014年教师批评与自我批评思想汇报
2014/09/20 职场文书
法律专业大学生职业生涯规划书:向目标一步步迈进
2014/09/22 职场文书
2014年前台接待工作总结
2014/12/05 职场文书
2015年信息中心工作总结
2015/05/25 职场文书
合理化建议书范文
2015/09/14 职场文书
2016年校园植树节广播稿
2015/12/17 职场文书
篮球拉拉队口号
2015/12/25 职场文书
画错魏国疆域啦!《派对咖孔明》动画因作画失误于官网致歉
2022/04/07 日漫