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 相关文章推荐
JavaScript中void(0)的具体含义解释
Feb 27 Javascript
javascript获取当前ip的代码
May 10 Javascript
javascript 随机展示头像实现代码
Dec 06 Javascript
jquery text(),val(),html()方法区别总结
Nov 04 Javascript
一个通过script自定义属性传递配置参数的方法
Sep 15 Javascript
JS常见问题之为什么点击弹出的i总是最后一个
Jan 05 Javascript
jQuery formValidator表单验证
Jan 07 Javascript
判断输入的字符串是否是日期格式的简单方法
Jul 11 Javascript
BootStrap便签页的简单应用
Jan 06 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
Apr 11 Javascript
一文帮你理解PReact10.5.13源码
Apr 03 Javascript
TS 类型兼容教程示例详解
Sep 23 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 常用类整理
2009/12/23 PHP
不支持fsockopen但支持culr环境下下ucenter与modoer通讯问题
2011/08/12 PHP
php实现统计网站在线人数的方法
2015/05/12 PHP
IE 当eval遇上function的处理
2011/08/09 Javascript
html中table数据排序的js代码
2011/08/09 Javascript
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
2015/05/04 Javascript
jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
2016/11/09 Javascript
js实现文字跑马灯效果
2017/02/23 Javascript
vue项目实现记住密码到cookie功能示例(附源码)
2018/01/31 Javascript
20行JS代码实现粘贴板复制功能
2018/02/06 Javascript
详解nodejs解压版安装和配置(带有搭建前端项目脚手架)
2018/12/06 NodeJs
Vue监听滚动实现锚点定位(双向)示例
2019/11/13 Javascript
基于ts的动态接口数据配置的详解
2019/12/18 Javascript
Vue-CLI与Vuex使用方法实例分析
2020/01/06 Javascript
JS数组方法reverse()用法实例分析
2020/01/18 Javascript
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
2015/04/25 Python
Python操作word常见方法示例【win32com与docx模块】
2018/07/17 Python
Python可视化mhd格式和raw格式的医学图像并保存的方法
2019/01/24 Python
Python语言进阶知识点总结
2019/05/28 Python
Python计算一个点到所有点的欧式距离实现方法
2019/07/04 Python
keras model.fit 解决validation_spilt=num 的问题
2020/06/19 Python
Python web框架(django,flask)实现mysql数据库读写分离的示例
2020/11/18 Python
前端H5 Video常见使用场景简介
2020/08/21 HTML / CSS
英国在线泳装店:Simply Swim
2019/05/05 全球购物
如何通过 CSS 写出火焰效果
2021/03/24 HTML / CSS
求职简历中个人的自我评价
2013/12/01 职场文书
大学军训感言
2014/01/10 职场文书
初中政治教学反思
2014/01/17 职场文书
世界遗产导游词
2015/02/13 职场文书
2015年公务员试用期工作总结
2015/05/28 职场文书
入党介绍人意见2015
2015/06/01 职场文书
人间正道是沧桑观后感
2015/06/15 职场文书
深度学习详解之初试机器学习
2021/04/14 Python
VUE中的v-if与v-show区别介绍
2022/03/13 Vue.js
Python各协议下socket黏包问题原理
2022/04/12 Python