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 动态加载 css 方法总结
Jul 11 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
Feb 02 Javascript
JS中typeof与instanceof之间的区别总结
Nov 14 Javascript
js 显示base64编码的二进制流网页图片
Apr 04 Javascript
js弹出对话框方式小结
Nov 17 Javascript
jquery调整表格行tr上下顺序实例讲解
Jan 09 Javascript
javaScript嗅探执行神器-sniffer.js
Feb 14 Javascript
Angular在一个页面中使用两个ng-app的方法
Feb 20 Javascript
Javascript 链式作用域详细介绍
Feb 23 Javascript
Vue导出页面为PDF格式的实现思路
Jul 31 Javascript
Layui 设置select下拉框自动选中某项的方法
Aug 14 Javascript
java实现单链表增删改查的实例代码详解
Aug 30 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
极典R601SW收音机
2021/03/02 无线电
php简单静态页生成过程
2008/03/27 PHP
php下使用strpos需要注意 === 运算符
2010/07/17 PHP
WordPress用户登录框密码的隐藏与部分显示技巧
2015/12/31 PHP
使用Codeigniter重写insert的方法(推荐)
2017/03/23 PHP
php命令行写shell实例详解
2018/07/19 PHP
PHP7导出Excel报ERR_EMPTY_RESPONSE解决方法
2019/04/16 PHP
jquery.ui.progressbar 中文文档
2009/11/26 Javascript
jQuery 选择器项目实例分析及实现代码
2012/12/28 Javascript
jQuery中:empty选择器用法实例
2014/12/30 Javascript
Bootstrap Metronic完全响应式管理模板学习笔记
2016/07/08 Javascript
Bootstrap 3 按钮标签实例代码
2017/02/21 Javascript
vue-router懒加载速度缓慢问题及解决方法
2018/11/25 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
2020/02/07 Javascript
前端深入理解Typescript泛型概念
2020/03/09 Javascript
微信小程序onShareTimeline()实现分享朋友圈
2021/01/07 Javascript
[01:56]2014DOTA2西雅图邀请赛 MVP外卡赛老队长精辟点评
2014/07/09 DOTA
python中wx将图标显示在右下角的脚本代码
2013/03/08 Python
Python编写屏幕截图程序方法
2015/02/18 Python
对tf.reduce_sum tensorflow维度上的操作详解
2018/07/26 Python
Python退出时强制运行一段代码的实现方法
2020/04/29 Python
Python几种常见算法汇总
2020/06/02 Python
Python多线程threading创建及使用方法解析
2020/06/17 Python
Python3爬虫关于识别点触点选验证码的实例讲解
2020/07/30 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
中国高端家电购物商城:顺电
2018/03/04 全球购物
施华洛世奇波兰官网:SWAROVSKI波兰
2019/06/18 全球购物
古驰英国官网:GUCCI英国
2020/03/07 全球购物
什么造成了Java里面的异常
2016/04/24 面试题
应聘医学检验人员自荐信
2013/09/27 职场文书
评析教师个人的自我评价
2014/02/19 职场文书
四风批评与自我批评发言稿
2014/10/14 职场文书
有限责任公司股东合作协议书范本
2014/10/30 职场文书
pytorch中的model=model.to(device)使用说明
2021/05/24 Python
Django与数据库交互的实现
2021/06/03 Python
深入讲解Vue中父子组件通信与事件触发
2022/03/22 Vue.js