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之选择组件的深入解析
Jun 19 Javascript
探讨在JQuery和Js中,如何让ajax执行完后再继续往下执行
Jul 09 Javascript
JS批量操作CSS属性详细解析
Dec 16 Javascript
JavaScript编写推箱子游戏
Jul 07 Javascript
javascript实现在指定元素中垂直水平居中
Sep 13 Javascript
javascript的正则匹配方法学习
Feb 24 Javascript
bootstrap布局中input输入框右侧图标点击功能
May 16 Javascript
JavaScript对Json的增删改属性详解
Jun 02 Javascript
Javascript的动态增加类的实现方法
Oct 20 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
Mar 07 Javascript
微信小程序后台持续定位功能使用详解
Aug 23 Javascript
微信小程序之左右布局的实现代码
Dec 13 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之PHP语法学习笔记1
2006/12/17 PHP
Laravel模型间关系设置分表的方法示例
2018/04/21 PHP
JS求平均值的小例子
2013/11/29 Javascript
JS使用getComputedStyle()方法获取CSS属性值
2014/04/23 Javascript
Js操作树节点自动折叠展开的几种方法
2014/05/05 Javascript
jQuery学习笔记之总体架构
2014/06/03 Javascript
js+csss实现的一个带复选框的下拉框
2014/09/29 Javascript
ECMAScript5(ES5)中bind方法使用小结
2015/05/07 Javascript
vue实现添加标签demo示例代码
2017/01/21 Javascript
基于jQuery代码实现圆形菜单展开收缩效果
2017/02/13 Javascript
推荐10款扩展Web表单的JS插件
2017/12/25 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
javascript和php使用ajax通信传递JSON的实例
2018/08/21 Javascript
js实现文件上传功能 后台使用MultipartFile
2018/09/08 Javascript
vue实现瀑布流组件滑动加载更多
2020/03/10 Javascript
解决vue自定义指令导致的内存泄漏问题
2020/08/04 Javascript
python smtplib模块自动收发邮件功能(一)
2018/05/22 Python
python中plot实现即时数据动态显示方法
2018/06/22 Python
python利用小波分析进行特征提取的实例
2019/01/09 Python
Win10环境python3.7安装dlib模块趟过的坑
2019/08/01 Python
与Django结合利用模型对上传图片预测的实例详解
2019/08/07 Python
django-crontab 定时执行任务方法的实现
2019/09/06 Python
Python之字典对象的几种创建方法
2020/09/30 Python
Python页面加载的等待方式总结
2021/02/28 Python
CSS3媒体查询(Media Queries)介绍
2013/09/12 HTML / CSS
赫里福德的一家乡村零售商店:Philip Morris & Son
2017/06/25 全球购物
早晨薰衣草在线女性精品店:Morning Lavender
2021/01/04 全球购物
JAVA和C++区别都有哪些
2015/03/30 面试题
办理房产过户的委托书
2014/09/14 职场文书
群众路线教育实践活动对照检查材料思想汇报(副处级领导)
2014/10/04 职场文书
个人作风建设心得体会
2014/10/22 职场文书
小学优秀教师先进事迹材料
2014/12/16 职场文书
考研经验交流会策划书
2015/11/02 职场文书
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis
详解php中流行的rpc框架
2021/05/29 PHP
vue3种table表格选项个数的控制方法
2022/04/14 Vue.js