首先讲原理,大家都知道JS是逐行执行,首先进入作用域只有有两种方式:

 1.当看到script标签的时候,进入到作用域,也就是内置的<script></script>

                     2.当调用一个方法的时候,进入到作用域。比如上面代码的fn();

这两点切记!切记!

                          那么,什么是作用域?用通俗的话来说,就是开辟一个特定空间,将解析到的东西放在里面。

                           解析前,还有一个道理,叫做JS预解析?为什么叫“预”?就是没执行之前先扫描一遍,将所有的var 和function存到作用域的仓库里。扫描出来所有var的值都预先是undefined!

我们首先进行预解析!

不多说,首先上第一题

 var a=100;

 function fn(){
      aert(a);

      var a=200;

      alert(a);
 }

 fn();
 alert(a);
 var a;
 alert(a);
 var a=300;
 alert(a);

这是第一题,大家可能有些人尝试着去看题目解析了,但是你知道解析的原理和顺序吗?光靠经验猜是没用的。计算机按照死命令执行,不会因为你用久了就知道你的心思去帮你完成:

通过预解析扫描全部var 和function,第1行,解析器看到了个var a ,就在仓库里定义 var a=undefined;

在第3行,解析到一个function fn(){...}  ,也丢到仓库里;继续,

在第11行,解析器跳过,前面提过了,解析器只会对var 和 function进行预解析,

到13行,又看到了个var a,这时重新定义,但是var a依旧是undefined,值不变,有些同学可能不懂,略作解释,前面提过了,所有在预解析里解析所有的var 都是未定义;同名直接覆盖,

后面没有var和function了,所以预解析结束,进行逐行执行

第1行,var a=100;这里我又要讲一个方法了,就是当js执行的时候,会找有没有+、-、*、/、++、--....如果有,就到预解析里去寻找对应的值进行修改变量var;这里a=100,有个“=”号,所以就去预解析仓库里修改var a=100;

第3行,函数,跳过。

第11行,调用了上面的函数,有些同学是不是想告诉我答案?100?  NO NO NO,请看进入作用域的条件方式第二条!!!进入了函数!!重新定义另一个作用域,进入预解析,整个函数里是不是只有一个变量var ?  然后就屁颠屁颠的跑到仓库里去定义 var a=undefined;(因为有var,所有重新定义这个函数内的变量a,不会和外面的产生冲突)解析完毕,进行执行,这下你知道alert(a);为什么会执行undefined了吧?  继续,接下来看到了var a=200;然后去作用域的仓库里修改var a=200;的值,接下来的alert(a)毫无疑问,弹出来200;  这个函数作用域主要的难点在于概念,你可能看到解析方法简单,但是真执行的时候,你总是会忘记进入新的作用域是会重新定义这个新“仓库”的;

第12行,根据第1行已经修改的变量得出 alert是100;

第13行,var a;首先,他这也是定义,但是没有修改变量,所以变量a依旧是100;

第14行,毫无疑问,弹出100;

第15行,修改变量 变量a=300;

第16行,弹出300;

以上附出图,希望同学们理解。

学计算机语言,最忌讳不学原理,可能前期你不会发觉,到后期,缺点就会慢慢展现出来;

还有第二题。。。

 alert(a);
 var a=1;
 alert(a);
 function a(){alert(a)};
 alert(a);
 var a=3;
 alert(a);
 function a(){alert(4)};
 alert(a);

学过上文的同学们试着解下这道题,不要直接看答案,吸收过的东西才是自己的;

好,咱们来解决这道题;

首先预解析,进入作用域

第2行,添加var a=undefined;

第4行,添加function a(){alert(a)};

第6行,添加var a=undefined,但是已存在,覆盖不变;

第8行,添加function a(){alert(4)};这是重点,同名函数,覆盖第4行的数据,

所以现在这个作用域仓库里只有一条数据 :function a(){alert(4)};大家或许会很纳闷,还有var a=undefined呢?

这里向大家解释下,当函数名称和变量方法一样的时候,变量就会被隐藏!对!是隐藏,不是覆盖,不是删除!

开始逐行执行,

大家先猜猜第一行执行什么?

有人说是undefined,也有人想的是弹出4;。。。

结果是alert(   function a() {alert(4)});对,你没看错,它弹出的是一整个函数。没执行的函数,我当初也是这么懵的;

接下来第2行,重新修改 ,隐藏函数function;var a=1

第3行,弹出1;

第4行,你们第一个念头是不是重新覆盖?NONONO,只有在预解析的情况下,函数名称和变量名一样的情况下才会让变量隐藏,执行的时候,他们相互间是没有关系的

第5行,所以,弹出1;

第6行,修改值var a=3;

第7行,弹出3;

第8行,又来混淆我们的耳目了,前面提过,执行的过程中,函数是不会替换相同变量名的;只作为一个方法被调用;

第9行,弹出3;

是不是被绕的有点晕了,还有呢!来个比较简单的!

 var a=1;
 function fn1(){
      alert(a);
      var a=2;
 }
 fn1();
 alert(a);

这道题自己做试试看吧。

然后我们开始,首先预解析

第1行 var a=undefined;

第2行 存储function fn1(){..}

解析完毕。

第1行,修改变量a=1;

第6行,进入作用域,开始预解析;

找到var  得到 var a=undefined;

开始处理,弹出undefined;

第7行,由于作用域只限制于嵌套,不含被嵌套,所以弹出1;

但是。。我稍微修改下

 var a=1;
 function fn1(){
      alert(a);
      a=2;
 }
 fn1();
 alert(a);

学会自己思考,才能消化,成为自己的知识,

首先 老规矩,预解析;

第1行 ,得到var a=undefined;(再次声明:预解析里的var都是undefined,直到逐行执行js代码var a=?将其修改变量)

开始执行

第1行,得出var a=1;

第6行,进入作用域,由于fn1里没有var   ,但是,需要这个a的值所以,会请求向上查找!这里提起一个概念,函数内的请求只会去上级查找,也就是嵌套,比如一个员工,他想申请涨工资,只能先到小组组长申请,再到组长那,再到主管,再往上就是经理,CEO,一级没有就继续往上传。到CEO都没解决,那就只能(not a defined)没戏了;

所以fn1()会弹出上级的变量a的值,也就是alert(1);  接下来,是一个全局变量,什么是全局变量,意思是重新定义所有的变量a的值就是a=2;当然,后续执行程序的时候还是能通过var a=?进行修改的;

第7行,弹出2;

觉得自己懂了?再来一发;

 var a=1;
 function fn1(a){
      alert(a);
      a=2;
 }
 fn1();
 alert(a);

嘿嘿,知道该怎么做了吗? 我仅仅添加了个参数a;

最好自己思考下,毕竟学习的知识不是一下子就能消化的;

动手!

首先预解析;

第1行,得到var a=undefined;

第2行,存储一个函数;function fn1(a){...};

开始逐行执行;

第行,修改变量a的值;

第6行,调用,进入作用域,这里重头戏来了,这里要再提一个概念,参数的传参形式和var的赋值形式是一样的;意思就是,你参数填的什么(比如现在的fn1(a)),就直接相当于默认的var a(var a=undefined);只是还没传入值;接着解析,在下面也没能找到var,所以直接弹出undefined;接下来的a=2只是一个传递参数(谁让和参数重名呢?),不会进行全局变量;fn1()执行完;

第7行,第一行的var a=1没有改变值,所以弹出1;

好了,希望我讲的大家能接受,如有不好的地方,欢迎留言指正!

JavaScript的作用域详解。的更多相关文章

  1. JavaScript 变量作用域 详解

    变量作用域要点 - 在JavaScript中没有块级作用域,只有函数作用域 - 在函数体内,局部变量的优先级高于同名的全局变量 - 在全局作用域编写代码时可以不写var语句,但声明局部变量时必须使用v ...

  2. javascript中的this作用域详解

    javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...

  3. JavaScript严格模式详解

    转载自阮一峰的博客 Javascript 严格模式详解   作者: 阮一峰 一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict m ...

  4. PHP常量、变量作用域详解(一)

    PHP 中的每个变量都有一个针对它的作用域,它是指可以在其中访问变量(从而访问它的值)的一个领域.对于初学者来说,变量的作用域是它们所驻留的页面.因此, 如果你定义了 $var,页面余下部分就可以访问 ...

  5. PHP变量作用域详解(二)

    学过C的人用PHP的时候一般会相当顺手,而且感到PHP太方便太轻松.但在变量作用域这方面却与C有不同的地方,搞不好会相当郁闷,就找不到错误所在.昨晚就与到这么一个问题,是全局变量在函数中的问题.今天搜 ...

  6. 从mixin到new和prototype:Javascript原型机制详解

    从mixin到new和prototype:Javascript原型机制详解   这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...

  7. [转]javascript console 函数详解 js开发调试的利器

    javascript console 函数详解 js开发调试的利器   分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...

  8. javascript 节点属性详解

    javascript 节点属性详解 根据 DOM,html 文档中的每个成分都是一个节点 DOM 是这样规定的:整个文档是一个文档节点每个 html 标签是一个元素节点包含在于 html 元素中的文本 ...

  9. (" use strict")Javascript 严格模式详解

    Javascript 严格模式详解 转载别人的博客内容,浏览了一遍,没有全部吸收,先保存一下链接 http://www.ruanyifeng.com/blog/2013/01/javascript_s ...

随机推荐

  1. MySQL二进制日志binlog简单使用

    MySQL数据库进行了哪些CUD操作,通过binlog二进制文件可以查看.binlog不仅可以记录CUD的操作(select操作不包括在内),还是主从备份的基础.主库的操作记录成binlog文件,定期 ...

  2. HDU [P2819] swap

    二分图行列匹配+输出路径 经典题,当且仅当一行匹配一列的时候,符合题意. 本题的难点在于如何输出路径,我们发现这个移动的过程就是将所有匹配选择排序,在选择排序时输出路径即可 #include < ...

  3. PowerShell 并行执行任务

    在 PowerShell 中可以轻松的执行后台任务并且让多个后台任务并行执行.本文介绍 PowerShell 中 Job 相关的一些命令,并通过 demo 演示如何在后台同时执行多个任务. Power ...

  4. AJAX面试题都在这里

    AJAX常见面试题 什么是AJAX,为什么要使用Ajax AJAX是"Asynchronous JavaScript and XML"的缩写.他是指一种创建交互式网页应用的网页开发 ...

  5. 【转】APACHE RewriteEngine用途

    首先要学会怎么设置 httpd.conf 的设置, 什么 ALL 就不用用说了 要看你的 httpd.conf 是否设置正确了,很简单,只要你在 .htaccess  里随便录入一些 比如 adbas ...

  6. mac给文件批量添加后缀名

    for i in *;do mv "$i" "$i.mp4";done

  7. 在linux内核中修改TCP MSS值

    MTU: Maxitum Transmission Unit 最大传输单元 MSS: Maxitum Segment Size 最大分段大小 MSS最大传输大小的缩写,是TCP协议里面的一个概念.MS ...

  8. Scrapy-多层爬取天堂图片网

    1.根据图片分类对爬取的图片进行分类 开发者选项 --> 找到分类地址         爬取每个分类的地址通过回调函数传入下一层 name = 'sky'start_urls = ['http: ...

  9. vue——安装并新建项目

    一.对于vue的安装: 1.安装vue之前先安装node,https://nodejs.org/zh-cn/download/,我装的是windows64位的: 2.下载好了之后就可以按照正常顺序安装 ...

  10. 由select引发的思考

    一.前言 网络编程里一个经典的问题,selec,poll和epoll的区别?这个问题刚学习编程时就接触了,当时看了材料很不明白,许多概念和思想没有体会,现在在这个阶段,再重新回头看这个问题,有一种豁然 ...