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确认框的三种使用方法
Dec 17 Javascript
javascript 兼容各个浏览器的事件
Feb 04 Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
Jul 05 Javascript
jQuery实现可以编辑的表格实例详解【附demo源码下载】
Jul 09 Javascript
jQuery搜索框效果实现代码(百度关键词联想)
Feb 25 Javascript
JS排序之冒泡排序详解
Apr 08 Javascript
JS排序算法之希尔排序与快速排序实现方法
Dec 12 Javascript
详解Angular5 服务端渲染实战
Jan 04 Javascript
vue2.0项目实现路由跳转的方法详解
Jun 21 Javascript
Electron-vue脚手架改造vue项目的方法
Oct 22 Javascript
Vue.js计算机属性computed和methods方法详解
Oct 12 Javascript
解决vue.js提交数组时出现数组下标的问题
Nov 05 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最常用的ini函数分析 针对PHP.ini配置文件
2010/04/22 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
一个可以显示阴历的JS代码
2007/03/05 Javascript
js计算页面刷新的次数
2009/07/20 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
2012/06/22 Javascript
js的匿名函数使用介绍
2013/12/11 Javascript
jQuery实现当按下回车键时绑定点击事件
2014/01/28 Javascript
jQuery如何将选中的对象转化为原始的DOM对象
2014/06/09 Javascript
原生javaScript实现图片延时加载的方法
2014/12/22 Javascript
JS实现鼠标箭头变成一个燃烧烛光效果的方法
2015/02/28 Javascript
Css3制作变形与动画效果
2015/07/24 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
前端微信支付js代码
2016/07/25 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
通过命令行生成vue项目框架的方法
2017/07/12 Javascript
深入理解Vue-cli搭建项目后的目录结构探秘
2017/07/13 Javascript
vue-router路由懒加载和权限控制详解
2017/12/13 Javascript
利用Angular2 + Ionic3开发IOS应用实例教程
2018/01/15 Javascript
vue element ui validate 主动触发错误提示操作
2020/09/21 Javascript
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
python编程测试电脑开启最大线程数实例代码
2018/02/09 Python
如何利用Anaconda配置简单的Python环境
2019/06/24 Python
django 微信网页授权登陆的实现
2019/07/30 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
2020/03/06 Python
屏蔽Django admin界面添加按钮的操作
2020/03/11 Python
CSS3中HSL和HSLA的简单使用示例
2015/07/14 HTML / CSS
最好的意大利皮夹克:D’Arienzo
2018/12/04 全球购物
美国折扣香水网站:The Perfume Spot
2020/12/12 全球购物
以思科路由器为例你写下单臂路由的配置命令
2013/08/03 面试题
this关键字的作用
2016/01/30 面试题
中专生自荐信
2013/10/12 职场文书
养牛场项目建议书
2014/05/13 职场文书
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
党的群众路线教育实践活动学习笔记范文
2014/11/06 职场文书
《生物入侵者》教学反思
2016/02/16 职场文书