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 相关文章推荐
JSQL 批量图片切换的实现代码
May 05 Javascript
理解Javascript_09_Function与Object
Oct 16 Javascript
Jquery 的扩展方法总结
Oct 01 Javascript
关于jquery ajax 调用带参数的webservice返回XML数据一个小细节
Jul 31 Javascript
理解Javascript闭包
Nov 01 Javascript
javascript中基本类型和引用类型的区别分析
May 12 Javascript
readonly和disabled属性的区别
Jul 26 Javascript
jQuery实现悬浮在右上角的网页客服效果代码
Oct 24 Javascript
详解JavaScript中js对象与JSON格式字符串的相互转换
Feb 14 Javascript
在vscode中统一vue编码风格的方法
Feb 22 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
Oct 28 Javascript
jQuery实现简单轮播图效果
Dec 27 jQuery
理解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
在线短消息收发的程序,不用数据库
2006/10/09 PHP
深入解析php中的foreach函数
2013/08/31 PHP
php实现的简单美国商品税计算函数
2015/07/13 PHP
php根据用户语言跳转相应网页
2015/11/04 PHP
PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
2016/01/04 PHP
php操作xml并将其插入数据库的实现方法
2016/09/08 PHP
php中序列化与反序列化详解
2017/02/13 PHP
PHP 实现浏览记录并按日期分组
2017/05/11 PHP
Laravel中encrypt和decrypt的实现方法
2017/09/24 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
javascript使用appendChild追加节点实例
2015/01/12 Javascript
js实现支持手机滑动切换的轮播图片效果实例
2015/04/29 Javascript
jQuery Mobile操作HTML5的常用函数总结
2016/05/17 Javascript
Angular2使用Angular-CLI快速搭建工程(二)
2017/05/21 Javascript
详解jquery选择器的原理
2017/08/01 jQuery
jQuery zTree搜索-关键字查询 递归无限层功能实现代码
2018/01/25 jQuery
angularjs使用gulp-uglify压缩后执行报错的解决方法
2018/03/07 Javascript
python单例模式实例分析
2015/04/08 Python
全面了解Python的getattr(),setattr(),delattr(),hasattr()
2016/06/14 Python
Python中摘要算法MD5,SHA1简介及应用实例代码
2018/01/09 Python
详解python的argpare和click模块小结
2019/03/31 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
Python 余弦相似度与皮尔逊相关系数 计算实例
2019/12/23 Python
Python 使用SFTP和FTP实现对服务器的文件下载功能
2020/12/17 Python
10分钟入门CSS3 Animation
2018/12/25 HTML / CSS
新西兰便宜隐形眼镜购买网站:QUICKLENS New Zealand
2019/03/02 全球购物
KOHLER科勒美国官网:国际著名卫浴橱柜领先品牌
2020/06/27 全球购物
单位领导证婚词
2014/01/14 职场文书
九年级数学教学反思
2014/02/02 职场文书
离职保密承诺书
2014/05/28 职场文书
法学求职信
2014/06/22 职场文书
2015年销售工作总结范文
2015/03/30 职场文书
Python3 使用pip安装git并获取Yahoo金融数据的操作
2021/04/08 Python
css display table 自适应高度、宽度问题的解决
2021/05/07 HTML / CSS
Python 的 sum() Pythonic 的求和方法详细
2021/10/16 Python
javascript进阶篇深拷贝实现的四种方式
2022/07/07 Javascript