JavaScript中的变量作用域介绍


Posted in Javascript onDecember 31, 2014

对于变量的作用域(scope),C、Java等语言采取的是“block scope”的方式。与之不同,JavaScript所采取的是“function scope”的方式 — 变量的作用域仅由所处的function决定,与if、for等逻辑块无关。比如,以下这个例子展示了JavaScript中与C、Java等语言不一样的行为:

function(){

  var s = 42;//s is visible throughout function

  if (s > 3) {

    var x = "test";//x is visible throughout function

    for(var i=0; i<10; i++){

      console.log(i);

    }

    console.log(i);//i is visible throughout function

  }

  console.log(i);

  console.log(x);

}

在C、Java等“block scope”的语言中,if语句、for语句等逻辑块结束后,在这些逻辑块内部定义的变量将会被销毁。JavaScript与之不同,只要一个变量定义在某function内,那么整个function内的所有代码均可访问到该变量,即使这些代码在变量定义之前:

function(){

  console.log(a);//undefined

  var a = "test";

  console.log(a);//test

}

在上述例子中,如果function中a从未被定义,那么console.log(a)将抛出ReferenceError。当function中对a进行定义后,即使这个定义在a变量调用语句之后,对a的调用也属于合法操作(如果对a变量的定义发生在调用语句之后,那么调用语句中a变量的值为undefined)。事实上,在function内用var关键词进行定义的所有变量,其定义操作都会被提至function的开头(赋值操作依然留在var定义的那一行),这在JavaScript中称之为hoisting。比如,上述代码就等价于:

function(){

  var a;

  console.log(a);//undefined

  a = "test";

  console.log(a);//test

}

变量的作用域链

联系JavaScript中变量的储存,可以很好的理解JS中的“function scope”与hoisting。由于变量是储存在全局对象或者函数调用对象上的,因此当在function中定义变量时,无论这个变量定义在function的什么地方,这次function调用所使用的函数调用对象中必然会出现一个与此变量同名的属性。如此一来,function中的任何地方都可以访问到该变量。

涉及到函数调用,JavaScript中还有一个更有趣的概念:变量的作用域链 — 由于变量是储存在全局对象或者函数调用对象上的,因此在访问变量时,可以从多个对象上获取值。以下面的代码为例:

var x = "test";

function(){

  //level-1 function

  var x = "temp";

  function(){

    //level-2 function

    var x = "real";

    //try to access x here. x will be "real".

  }

}

在上述代码中2级函数(level-2 function)的内部,当试图访问x变量时,程序可以从3个对象上搜索相应的属性值:调用2级函数所使用的函数调用对象、调用1级函数所使用的函数调用对象、全局对象 — 根据函数定义的嵌套关系,JavaScript将生成一个由全局对象和函数调用对象所组成的对象链。访问变量时,程序将从离访问语句最近的那个对象开始搜索,如果没有搜索到,则在对象链中上一级的对象中继续进行搜索,直至全局对象。

由于这个对象链与变量的作用域有关,因此也叫做“作用域链”。

如果需要临时改变作用域链,将某个对象插入到作用域链的最前端(作为最先访问到的那个函数对象),可以使用with语句:

with(o){

  //code use properties of object o.

}

不过,在JavaScript严格模式下,with语句是被禁用的;即使在非严格模式下,也不推荐使用with语句。

Javascript 相关文章推荐
关于javascript中的parseInt使用技巧
Sep 03 Javascript
JavaScript中出现乱码的处理心得
Dec 24 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
Dec 19 Javascript
javascript学习笔记(十) js对象 继承
Jun 19 Javascript
Jquery中给animation加更多的运作效果实例
Sep 05 Javascript
jQuery复制表单元素附源码分享效果演示
Sep 30 Javascript
深入解析JavaScript中的数字对象与字符串对象
Oct 21 Javascript
jquery自定义显示消息数量
Dec 19 jQuery
微信小程序实现横向增长表格的方法
Jul 24 Javascript
js实现一个页面多个倒计时的3种方法
Feb 25 Javascript
JS控制只能输入数字并且最多允许小数点两位
Nov 24 Javascript
原生javascript如何实现共享onload事件
Jul 03 Javascript
JavaScript中的变量定义与储存介绍
Dec 31 #Javascript
JavaScript中的操作符==与===介绍
Dec 31 #Javascript
jQuery中[attribute]选择器用法实例
Dec 31 #Javascript
JavaScript中的比较操作符&gt;、=、
Dec 31 #Javascript
javascript 操作符(~、&amp;、|、^、)使用案例
Dec 31 #Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
Dec 31 #Javascript
JavaScript中的eval()函数使用介绍
Dec 31 #Javascript
You might like
php中file_get_content 和curl以及fopen 效率分析
2014/09/19 PHP
分享PHP计算两个日期相差天数的代码
2015/12/23 PHP
PHP守护进程化在C和PHP环境下的实现
2017/11/21 PHP
nodejs分页类代码分享
2014/06/17 NodeJs
全面解析Bootstrap表单使用方法(表单样式)
2015/11/24 Javascript
js实现商城星星评分的效果
2015/12/29 Javascript
原生JS封装ajax 传json,str,excel文件上传提交表单(推荐)
2016/06/21 Javascript
AngularJS入门教程中SQL实例详解
2016/07/27 Javascript
angular双向绑定模拟探索
2016/12/26 Javascript
js绑定事件和解绑事件
2017/04/27 Javascript
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
jQuery pjax 应用简单示例
2018/09/20 jQuery
JavaScript学习笔记之图片库案例分析
2019/01/08 Javascript
JavaScript计算出两个数的差值
2020/03/19 Javascript
js 将多个对象合并成一个对象 assign方法的实现
2020/09/24 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
[01:01:52]完美世界DOTA2联赛PWL S2 GXR vs Magma 第二场 11.25
2020/11/26 DOTA
Python中__name__的使用实例
2015/04/14 Python
Python实战小程序利用matplotlib模块画图代码分享
2017/12/09 Python
解决Python一行输出不显示的问题
2018/12/03 Python
利用anaconda作为python的依赖库管理方法
2019/08/13 Python
python数据分析工具之 matplotlib详解
2020/04/09 Python
Python txt文件如何转换成字典
2020/11/03 Python
日常奢侈品,轻松购物:Verishop
2019/08/20 全球购物
餐饮部总监岗位职责范文
2014/02/13 职场文书
文明餐桌行动实施方案
2014/02/19 职场文书
大学生应聘导游自荐信
2014/06/02 职场文书
就业协议书样本
2014/08/20 职场文书
带刀到教室的检讨书
2014/10/04 职场文书
中班上学期个人总结
2015/02/12 职场文书
中学生学习保证书
2015/02/26 职场文书
党支部审查意见
2015/06/02 职场文书
goland 设置project gopath的操作
2021/05/06 Golang
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python
Go gorilla/sessions库安装使用
2022/08/14 Golang