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 相关文章推荐
jQuery Pagination Ajax分页插件(分页切换时无刷新与延迟)中文翻译版
Jan 11 Javascript
用JavaScript修改CSS属性的代码
May 06 Javascript
javascript不同类型数据之间的运算的转换方法
Feb 13 Javascript
js调试工具Console命令详解
Oct 21 Javascript
javascript 事件处理示例分享
Dec 31 Javascript
javaScript实现滚动新闻的方法
Jul 30 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)
May 11 Javascript
Vue2 配置 Axios api 接口调用文件的方法
Nov 13 Javascript
了解在JavaScript中将值转换为字符串的5种方法
Jun 06 Javascript
微信小程序导入Vant报错VM292:1 thirdScriptError的解决方法
Aug 01 Javascript
加速vue组件渲染之性能优化
Apr 09 Javascript
精读《Vue3.0 Function API》
May 20 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
便携利器 — TECSUN PL-365简评
2021/03/02 无线电
php连接mysql数据库代码
2009/03/10 PHP
PHP笔记之:基于面向对象设计的详解
2013/05/14 PHP
解密ThinkPHP3.1.2版本之独立分组功能应用
2014/06/19 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
ExtJS 设置级联菜单的默认值
2010/06/13 Javascript
javaScript(JS)替换节点实现思路介绍
2013/04/17 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
JavaScript中的return语句简单介绍
2015/12/07 Javascript
使用jquery提交form表单并自定义action的实现代码
2016/05/25 Javascript
angularJS 指令封装回到顶部示例详解
2017/01/22 Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
2017/06/08 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
Bootstrap Table列宽拖动的方法
2018/08/15 Javascript
JS实现的检验身份证格式并输出出生日期,年龄,性别,出生地示例
2019/05/17 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
2019/08/01 Javascript
在vue和element-ui的table中实现分页复选功能
2019/12/04 Javascript
使用JavaScript通过前端发送电子邮件
2020/05/22 Javascript
React冒泡和阻止冒泡的应用详解
2020/08/18 Javascript
[01:09:24]Ti4开幕式
2014/07/19 DOTA
老生常谈Python序列化和反序列化
2017/06/28 Python
python动态文本进度条的实例代码
2020/01/22 Python
python中数据库like模糊查询方式
2020/03/02 Python
Python接口开发实现步骤详解
2020/04/26 Python
python 异步async库的使用说明
2020/05/04 Python
python Django 反向访问器的外键冲突解决
2020/05/20 Python
Linux不知道文件后缀名怎么判断文件类型
2014/08/21 面试题
产品质量承诺书范文
2014/03/27 职场文书
2014年安全生产目标责任书
2014/07/23 职场文书
教师批评与自我批评(群众路线)
2014/10/15 职场文书
员工家属慰问信
2015/03/24 职场文书
宿舍卫生管理制度
2015/08/05 职场文书
使用 JavaScript 制作页面效果
2021/04/21 Javascript
FFmpeg视频处理入门教程(新手必看)
2022/01/22 杂记
Java+swing实现抖音上的表白程序详解
2022/06/25 Java/Android
详解flex:1什么意思
2022/07/23 HTML / CSS