Javascript中的作用域及块级作用域


Posted in Javascript onDecember 08, 2017

一、块级作用域的说明

在学习JavaScript的变量作用域之前,我们应当明确几点:

a、JavaScript的变量作用域是基于其特有的作用域链的。

b、JavaScript没有块级作用域。

c、函数中声明的变量在整个函数中都有定义。

  javascript的变量作用域,与平时使用的类C语言不同,例如C#中的代码:

static void Main(string[] args)
{
   if(true)
   {
    int number=10;
   }
  Console.WriteLine(number);
}

 这段代码进行编译,是无法通过的,因为"当前上下文不存在number".

  因为这里变量的作用域是由花括号限定的,称为块级作用域。

       在块级作用域下,所有的变量都在定义的花括号内,从定义开始到花括号结束这个范围内可以使用,出了这个范围就是无法访问,也就是说

if(true)
{
  int number=10;
  Console.WriteLine(number);
}

这样可以访问,因为变量的定义与使用在同一个花括号内。

但是在javascript中没有块级作用域的概念。

二、javascript中的作用域

 1、函数限定变量作用域

       在javascript中,函数里面定义的变量,,可以在函数里面被访问,但在函数外无法访问,代码:

<script type="text/javascript">
  var num=function()
  {
   var number=10;
  };
  try{
    alert(number);
  }catch(e)
  {
    alert(e);
  } 
</script>

    代码运行时,会抛出一个异常,变量number没有定义,是因为定义在函数中的变量无法再函数外使用,在函数内可以任意使用,即使在赋值之前:

<script type="text/javascript">
 var num=function(){
    alert(number);
    var number=10;
    alert(number);
 };
 try{
   num();
 }catch(e){
  alert(e);
 }
</script>

    这段代码运行后,不会抛出错误,弹出两次,分别是undefined和10

 2.子域访问父域

     函数可以限定变量的作用域,那么在函数中的函数就为该作用域的子域,在子域中的代码可以访问到父域中的变量,代码如下:

<script type="text/javascript">
 var func=function(){
    var number=10;
    var sub_func=function(){
      alert(num);
    };
   sub_func();
};
func();
</script>

 这段代码执行得到的结果是10,但是在子域中访问父域的代码也是有条件的

<script type="text/javascript">
 var func=function(){
    var number=10;
    var sub_func=function(){
      var num=20;
      alert(num);
    };
   sub_func();
};
func();
</script>

这段代码比前面多了一个"var num=20;",这句代码在子域中,那么子域访问父域的情况就发生了变化,这段代码打印的结果是20,此时子域访问的num是子域中的变量,而不是父域中的。由此可见访问有一定规则可言,在javascript中使用变量,javascript解释器首先在当前作用域中搜索是否有该变量的定义,如果有,就是用这个变量,如果没有就到父域中寻找变量,依次类推,直到最顶级作用域,仍然没有找到就抛出异常"变量未定义",代码如下:

<script type="text/javascript">
 (function (){
   var num=10;
   (function (){
     var num=20;
     (function(){
     alert(num);
      })();
   })();
  })();
</script>

这段代码执行后打印出20,如果将"var num=20"取掉,那么打印的就是10.同样去掉"var num=10",那么就会出现未定义的错误。

下面介绍下JS作用域与块级作用域

作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期。讲到这里,首先理解两个概念:块级作用域与函数作用域。

什么是块级作用域呢?

任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。

函数作用域就好理解了(*^__^*) ,定义在函数中的参数和变量在函数外部是不可见的。

大多数类C语言都拥有块级作用域,JS却没有。请看下文demo:

//C语言 
#include <stdio.h> 
void main() 
{ 
  int i=2; 
  i--; 
  if(i) 
  { 
    int j=3; 
  } 
  printf("%d/n",j); 
}

运行这段代码,会出现“use an undefined variable:j”的错误。可以看到,C语言拥有块级作用域,因为j是在if的语句块中定义的,因此,它在块外是无法访问的。 

而JS是如何表现的呢,再看另一个demo:

functin test(){ 
 for(var i=0;i<3;i++){   
 } 
 alert(i); 
} 
test();

 运行这段代码,弹出"3",可见,在块外,块中定义的变量i仍然是可以访问的。也就是说,JS并不支持块级作用域,它只支持函数作用域,而且在一个函数中的任何位置定义的变量在该函数中的任何地方都是可见的。 

那么我们该如何使JS拥有块级作用域呢?是否还记得,在一个函数中定义的变量,当这个函数调用完后,变量会被销毁,我们是否可以用这个特性来模拟出JS的块级作用域呢?看下面这个DEMO:

function test(){ 
 (function (){ 
 for(var i=0;i<4;i++){ 
 } 
 })(); 
 alert(i); 
} 
test();

这时候再次运行,会弹出"i"未定义的错误,哈哈,实现了吧~~~这里,我们把for语句块放到了一个闭包之中,然后调用这个函数,当函数调用完毕,变量i自动销毁,因此,我们在块外便无法访问了。 

JS的闭包特性is the most important feature((*^__^*) 大家懂的)。在JS中,为了防止命名冲突,我们应该尽量避免使用全局变量和全局函数。那么,该如何避免呢?不错,正如上文demo所示,我们可以把要定义的所有内容放入到一个

(function (){ 
//内容 
})();

总结

以上所述是小编给大家介绍的Javascript中的作用域及块级作用域,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery判断单个复选框是否被选中的代码
Sep 03 Javascript
jquery 页面全选框实践代码
Apr 02 Javascript
ExtJs GridPanel简单的增删改实现代码
Aug 26 Javascript
浅谈jQuery中replace()方法
May 13 Javascript
JS 清除字符串数组中,重复元素的实现方法
May 24 Javascript
jQuery实现点击表格单元格就可以编辑内容的方法【测试可用】
Aug 01 Javascript
实现一个简单的vue无限加载指令方法
Jan 10 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
Jan 12 Javascript
jQuery Validate 数组 全部验证问题
Jan 12 Javascript
Mongoose实现虚拟字段查询的方法详解
Aug 15 Javascript
element-ui表格数据转换的示例代码
Aug 24 Javascript
Node.js API详解之 util模块用法实例分析
May 09 Javascript
Vue中自定义全局组件的实现方法
Dec 08 #Javascript
Vue中的Vux配置指南
Dec 08 #Javascript
利用10行js代码实现上下滚动公告效果
Dec 08 #Javascript
vue axios 二次封装的示例代码
Dec 08 #Javascript
微信小程序使用audio组件播放音乐功能示例【附源码下载】
Dec 08 #Javascript
js断点调试心得分享(必看篇)
Dec 08 #Javascript
微信小程序使用video组件播放视频功能示例【附源码下载】
Dec 08 #Javascript
You might like
PhpMyAdmin出现export.php Missing parameter: what /export_type错误解决方法
2012/08/09 PHP
深入PHP与浏览器缓存的分析
2013/06/03 PHP
分享一则PHP定义函数代码
2015/02/26 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
js滚动条回到顶部的代码
2011/12/06 Javascript
select、radio表单回显功能实现避免使用jquery载入赋值
2013/06/08 Javascript
JavaScript中用toString()方法返回时间为字符串
2015/06/12 Javascript
简单介绍JavaScript中字符串创建的基本方法
2015/07/07 Javascript
Bootstrap编写一个兼容主流浏览器的受众巨幕式风格页面
2016/07/01 Javascript
bootstrap实现每隔5秒自动轮播效果
2016/12/20 Javascript
URL中“#” “?” &amp;“”号的作用浅析
2017/02/04 Javascript
详解AngularJS脏检查机制及$timeout的妙用
2017/06/19 Javascript
原生JS实现的自动轮播图功能详解
2018/12/28 Javascript
[01:59]DOTA2首部纪录片《Free to play》预告片
2014/03/12 DOTA
[01:30:54]《加油DOTA》 第三期
2014/08/18 DOTA
[49:41]NB vs NAVI Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
Python实现简单HTML表格解析的方法
2015/06/15 Python
python使用xlrd模块读取xlsx文件中的ip方法
2019/01/11 Python
Python中 Global和Nonlocal的用法详解
2020/01/20 Python
Python模块future用法原理详解
2020/01/20 Python
使用python检查yaml配置文件是否符合要求
2020/04/09 Python
Python爬虫之Selenium实现窗口截图
2020/12/04 Python
Python爬虫开发与项目实战
2020/12/16 Python
css3 伪类选择器快速复习小结
2019/09/10 HTML / CSS
美国彩妆品牌:Coastal Scents
2017/04/01 全球购物
英国第一家领先的在线处方眼镜零售商:Glasses Direct
2018/02/23 全球购物
施惠特软件测试面试题以及笔试题
2015/05/13 面试题
幼儿园教师辞职信
2014/01/18 职场文书
关于奉献的演讲稿
2014/05/21 职场文书
企业职业病防治方案
2014/05/29 职场文书
社会工作专业求职信
2014/07/15 职场文书
诚实守信道德模范事迹材料
2014/08/15 职场文书
2014幼儿园大班工作总结
2014/11/10 职场文书
拿破仑传读书笔记
2015/07/01 职场文书
2020年元旦祝福语录,总有适合你的
2019/12/31 职场文书