JavaScript的作用域详解。
首先讲原理,大家都知道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的作用域详解。的更多相关文章
- JavaScript 变量作用域 详解
变量作用域要点 - 在JavaScript中没有块级作用域,只有函数作用域 - 在函数体内,局部变量的优先级高于同名的全局变量 - 在全局作用域编写代码时可以不写var语句,但声明局部变量时必须使用v ...
- javascript中的this作用域详解
javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...
- JavaScript严格模式详解
转载自阮一峰的博客 Javascript 严格模式详解 作者: 阮一峰 一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict m ...
- PHP常量、变量作用域详解(一)
PHP 中的每个变量都有一个针对它的作用域,它是指可以在其中访问变量(从而访问它的值)的一个领域.对于初学者来说,变量的作用域是它们所驻留的页面.因此, 如果你定义了 $var,页面余下部分就可以访问 ...
- PHP变量作用域详解(二)
学过C的人用PHP的时候一般会相当顺手,而且感到PHP太方便太轻松.但在变量作用域这方面却与C有不同的地方,搞不好会相当郁闷,就找不到错误所在.昨晚就与到这么一个问题,是全局变量在函数中的问题.今天搜 ...
- 从mixin到new和prototype:Javascript原型机制详解
从mixin到new和prototype:Javascript原型机制详解 这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...
- [转]javascript console 函数详解 js开发调试的利器
javascript console 函数详解 js开发调试的利器 分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...
- javascript 节点属性详解
javascript 节点属性详解 根据 DOM,html 文档中的每个成分都是一个节点 DOM 是这样规定的:整个文档是一个文档节点每个 html 标签是一个元素节点包含在于 html 元素中的文本 ...
- (" use strict")Javascript 严格模式详解
Javascript 严格模式详解 转载别人的博客内容,浏览了一遍,没有全部吸收,先保存一下链接 http://www.ruanyifeng.com/blog/2013/01/javascript_s ...
随机推荐
- PowerShell 并行执行任务
在 PowerShell 中可以轻松的执行后台任务并且让多个后台任务并行执行.本文介绍 PowerShell 中 Job 相关的一些命令,并通过 demo 演示如何在后台同时执行多个任务. Power ...
- centos java环境搭建
我个人配置的是阿里云centos 7.4 64bit 不存在openjdk 看下面内容的情况下看是否存在openjdk java -version 如果返回java版本值,则存在openjdk,需要卸 ...
- 本地创建yum源并安装lnmp
注意:安装系统时,文件类型要未xfs类型,root要分配最多的空间 1.挂载安装光盘mount -t iso9660 -o loop CentOS-7-x86_64-DVD-1511.iso /mnt ...
- Ubuntu16.04+Apache虚拟主机配置详解
在window下,Apache的配置文件是httpd.conf,但在Linux下安装了Apache后发现其配置并不像window下那么简单,Linux下Apache将各个设置项分在了不同的配置文件中, ...
- Discuz的安装与使用
Discuz的安装与使用 一.Discuz的安装 由于本机已经安装好XAMPP集成工具,后续Discuz访问数据库以及服务器等都是基于XAMPP环境.在主机localhost根目录下新建bbs文件夹. ...
- unbuntu 系统登录华南师范大学校园网的方法
最近刚装了unbuntu 系统,刚开始网络连接遇到了点小问题,原来是校园网不知道怎么认证,于是向好基友请教了下,得出快捷的方法如下: 下载学校网络的认证客户端,记住位置,一般都是默认下载地址是 Dow ...
- JPA数据懒加载LAZY配合事务@Transactional使用(三)
上篇博文<JPA数据懒加载LAZY和实时加载EAGER(二)>讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数 ...
- java实现 redis的发布订阅(简单易懂)
redis的应用场景实在太多了,现在介绍一下它的几大特性之一 发布订阅(pub/sub). 特性介绍: 什么是redis的发布订阅(pub/sub)? Pub/Sub功能(means Publ ...
- Asp.Net Core2.0 基于QuartzNet任务管理系统
Quartz.NET官网地址:https://www.quartz-scheduler.net/ Quartz.NET文档地址:https://www.quartz-scheduler.net/doc ...
- PHP安全、Sql防注入安全汇总
利用Mysqli和PDO 产生原因 主要就是一些数据没有经过严格的验证,然后直接拼接 SQL 去查询.导致漏洞产生,比如: $id = $_GET['id']; $sql = "SELECT ...