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 动态创建元素的方式介绍及应用
Apr 21 Javascript
js获取html页面节点方法(递归方式)
Dec 13 Javascript
浅谈javascript中return语句
Jul 15 Javascript
JS把内容动态插入到DIV的实现方法
Jul 19 Javascript
BootStrap 附加导航组件
Jul 22 Javascript
jQuery插件ajaxFileUpload使用详解
Jan 10 Javascript
详解支持Angular 2的表格控件
Jan 19 Javascript
bootstrapValidator.min.js表单验证插件
Feb 09 Javascript
让微信小程序支持ES6中Promise特性的方法详解
Jun 13 Javascript
js 奇葩技巧之隐藏代码
Aug 11 Javascript
微信小程序中为什么使用var that=this
Aug 27 Javascript
js实现点击按钮随机生成背景颜色
Sep 05 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 和 MySQL 开发的 8 个技巧
2007/01/02 PHP
收藏的PHP常用函数 推荐收藏保存
2010/02/21 PHP
关于shopex同步ucenter的redirect问题,导致script不运行
2013/04/10 PHP
ubuntu10.04配置 nginx+php-fpm模式的详解
2013/06/03 PHP
深入PHP FTP类的详解
2013/06/13 PHP
解析php中session的实现原理以及大网站应用应注意的问题
2013/06/17 PHP
PHP实现的分解质因数操作示例
2018/08/01 PHP
js表数据排序 sort table data
2009/02/18 Javascript
jquery ajax提交表单数据的两种实现方法
2010/04/29 Javascript
解决JS中乘法的浮点错误的方法
2014/01/03 Javascript
JavaScript常用的返回,自动跳转,刷新,关闭语句汇总
2015/01/13 Javascript
asp.net+js实现金额格式化
2015/02/27 Javascript
JavaScript实现在页面间传值的方法
2015/04/07 Javascript
在线所见即所得HTML编辑器的实现原理浅析
2015/04/25 Javascript
使用jQuery的load方法设计动态加载及解决被加载页面js失效问题
2017/03/01 Javascript
JavaScript实现多重继承的方法分析
2018/01/09 Javascript
如何为你的JavaScript代码日志着色详解
2019/04/08 Javascript
在vue中获取微信支付code及code被占用问题的解决方法
2019/04/16 Javascript
Vue开发之封装上传文件组件与用法示例
2019/04/25 Javascript
JS监听组合按键思路及实现过程
2020/04/17 Javascript
利用numpy和pandas处理csv文件中的时间方法
2018/04/19 Python
python二维列表一维列表的互相转换实例
2018/07/02 Python
python3.4控制用户输入与输出的方法
2018/10/17 Python
Python QQBot库的QQ聊天机器人
2019/06/19 Python
Django框架视图函数设计示例
2019/07/29 Python
HTML5 Canvas阴影使用方法实例演示
2013/08/02 HTML / CSS
超市采购员岗位职责
2014/02/01 职场文书
施工安全承诺书
2014/05/22 职场文书
服务承诺书怎么写
2014/05/24 职场文书
公司副总经理任命书
2014/06/05 职场文书
入党介绍人考察意见
2015/06/01 职场文书
重阳节简报
2015/07/20 职场文书
十一月早安语录:把心放轻,人生就是一朵自在的云
2019/11/04 职场文书
22句经典语录:送给优柔寡断和胡思乱想的朋友们
2019/12/13 职场文书
vue引入Excel表格插件的方法
2021/04/28 Vue.js
python flappy bird小游戏分步实现流程
2022/02/15 Python