js变量提升_学习笔记:JS中的作用域和预解析

知识总结:谢静贤、汤昊

在javascript中作用域是非常重要的,本文将会说明作用域以及我们在工作,以及面试中的一些面试题,如果有不足的地方希望大家可以评论指出来,自己一定会及时的改正错误,避免大家走入一些误区。

一:作用域

二.预解析  

三.作用域链

四.函数和变量提升

五.预解析中的一些变态机制 

一、作用域

一般情况下,一段代码中所用到的名字并不总是有效可用的,而限定这个名字(变量)的可用性的代码范围就是这个名字的作用域,可用有效的减少变量名冲突

1、js的作用域(es6)之前:全局作用域,局部作用域

2、全局作用域:整个script标签 或者是单独的JS文件

3、局部作用域(函数作用域),在函数内部就是局部作用域,这个变量名只能在函数内部使用

4、变量作用域

根据作用域的不同,变量分为全局变量,局部变量

 注意

如果在函数内部没有声明直接赋值的变量也叫全局变量 

 函数的形参也是局部变量

 全局变量:只有浏览器关闭的时候才会销毁,比较占内存

 局部变量:当程序执行完毕就会销毁,比较节约内存

5、现阶段JS没有块级作用域

在es6中有块级作用域

块级作用域 {} if{} for{}

6、作用域链

内部函数访问外部函数 采用的就是链式这种结果就是作用域链 (就近原则)

二.预解析

1、什么是预解析:

预解析:在当前作用域下,js代码执行之前,浏览器会把带有var和function关键字的提前进行声明(var只声明)或定义(function声明并定义),并在内存中安排好。然后再从上到下执行js语句。

2、预解析的作用:

变量提升(Hoisting):在JS中,浏览器会把定义在后面的(变量或函数)提升到前面当前作用域的top处。也就是说在当前作用域中我们在js代码未执行到声明之前就可以使用了;

var和function预解析的不同

Var

var在预解释的时候,只进行提前的声明,只要是通过var定义的,不管变量或者函数,都是赋值undefined;

Function

function在预解释的时候提前的声明和定义都完成了,但是它储存数据的空间里存储的是字符串,没有任何意义。

三.作用域链

  • JavaScript代码中至少有一个作用域, 即全局作用域。

  • 凡是代码中有函数,那么这个函数就构成另一个作用域。

  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。

  • 将这样的所有的作用域列出来,可以形成的结构就称之为作用域链。

  • 0596ee3ad7004bdc51b688ffd0e8cf8e.png

  • 0ff5c4a3e8e0f6e331f63d1e14e643b7.png

四. 函数和变量提升

1.  函数提升(函数预解析):函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

2.变量提升(变量预解析):变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。

变量提升和函数提升基本上是面试必问题目

10d0804d5e6a4b0c5cd316e340eb3593.png

下面我们针对这个例子解析一下

我们知道变量和函数定义都会提升到作用域最前边

唯一需要确认的是变量和函数的先后顺序

我们预想 函数是用会不会提升到最前边呢?

befc1751081078283183b57fda3416d1.png

按照我们预想的解析结果应该是

// undefined // undefined // 报错

理由 函数在上var在下,第一个console时a未赋值,其结果是undefined,if为false 只剩最后一个console也是undefined 最后a is not a function.

不过结果是

026ec99b2f3b9eb6875651d880868e4c.png

我机智的认为 预想错了?

191395cfbb07cfa4628d799efd9a4728.png

这样?对比一下结果人工解析结果 :1、a() 2、1 3、1 4、a() 报错

浏览器执行结果:

8c7228956f40ce06358d3b34a3b2980d.png

看到这里一切完美,不过我还是重新搜索了一些高质量文章,发现我错了,虽然执行结果是对的,不过浏览器和人工解析还是不一样的,和我们最开始预想的一样,函数优先。

既然标题说到了变量 和 函数,我们就一块来说说

8b4203a5cbb9f473c0367c74f0efa265.png

首先上边已经说到我们预想和认为的是错的。

正确解析顺序是这样的

f02d8fca4aa86b2aa8ef98abb063fe19.png

但是,这个但是很重要浏览器执行结果是:

241af57fd27dcb74ecc648ed580dcdc8.png

why?这就要讲讲我所了解到的原理。

同名变量和函数,函数会提升到最前边,变量其次,那为什么结果不是我们人工执行的undefined呢?原因是 变量会被忽略,是的是忽略。。。

305a45b1d715d14ef52acbe6dcbbc929.png

完美!

还有呢?是的还有同名变量是怎样的顺序,同名函数是怎样的顺序。

同名变量

205632786070d514c9120337b95f43b4.png

同名变量,声明会被提升,后边会忽略。

同名函数

419dfd23feaf23f968a64d897c868983.png

5473faaccf3aedfd3048fdde11abdc46.png

我想你已经猜到了,同名函数会被覆盖。

五.预解析中的一些变态机制

不管条件是否成立,都要把带var的进行提前的声明

2a8f0bba339445202a9836fddf52a905.png

JavaScript进行预解析的时候,会忽略所有if条件,因为在ES6之前并没有块级作用域的概念。本例中会先将num预解析,而预解析会将该变量添加到window中,作为window的一个属性。那么 'num' in window 就返回true,取反之后为false,这时代码执行不会进入if块里面,num也就没有被赋值,最后console.log(num)输出为undefined。

return下的代码依然会进行预解析

b7ca1ef3dfc84bcfe851348ca164d5ac.png

函数体中return下面的代码,虽然不再执行了,但是需要进行预解析,return中的代码,都是我们的返回值,所以不进行预解析。

您的点赞是我继续下去的动力,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/271202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS Engine开发之旅09--几何对象和空间参考

1.Geometry Geometry 是 GIS 中使用最为广泛的对象集之一,用户在创建、删除、编辑和进行地理分析的时候,就是处理一个包含几何形体的矢量对象;除了显示要素意外,控件对象选择,要素符号化,标注要素&#xf…

项目管理:软件工程相关知识笔记

1、软件工程概念介绍软件工程是指应用计算机科学、数学、管理科学等原理,以工程化的原则和方法来解决软件问题的工程,其主要目的是提高软件生产率、提高软件质量、降低软件成本。2、软件工程学的组成软件开发技术:软件开发方法学、软件工具、…

android开发java环境_搭建Android开发环境 - Android - mobile - JavaEye论坛

Android的开发现在是如火如荼,逞现在不是很忙了,学习了下,这里记录下了在windows在如何搭建Android开发环境,对自己是个记录,对新入门的兄弟姐妹们可以参考一下!(1)安装JDK,省略。(2)下载Androi…

updatebyprimarykeyselective的where条件是全部字段_ArcGIS 字段计算器

使用键盘输入值并不是编辑表中值的唯一方式。在某些情况下,为了设置字段值,可能要对单条记录甚至是所有记录执行数学计算。您可以对所有记录或选中记录执行简单计算和高级计算。此外,还可以在属性表中的字段上计算面积、长度、周长和其他几何…

项目管理基础:软件生命周期概念介绍

1、软件生命周期定义软件产品或软件系统要经历孕育、诞生、成长、成熟、衰亡等阶段称为软件的生命周期。2、软件生命周期阶段组成软件的生命周期由可行性分析与项目开发计划、需求分析、总体设计、详细设计、编码、单元测试、综合测试、维护阶段。2.1 可行性分析与项目开发计划…

jvm栈和寄存器

jvm栈和寄存器 总结

项目管理基础:项目的生存周期模型

1、概念介绍软件生命周期模型是一个包含软件产品开发、运行和维护中有关过程、活动和任务的框架,它覆盖了系统从需求定义到系统使用的结束阶段。特点:描述了开发的主要阶段定义了每个阶段需要完成的任务和过程规范了每个阶段的输入输出提供了一个标准框架…

jps显示当前所有java进程pid

很多Java命令都在jdk的JAVA_HOME/bin/目录下面,jps也不例外,他就在bin目录下,所以,他是java自带的一个命令。 jps(Java Virtual Machine Process Status Tool) 是java提供的一个显示当前所有java进程pid的命令,适合在…

jvm内存结构_浅谈JVM内存结构

JVM 可以分为 5 个部分,分别是:类加载器(Class Loader):加载字节码文件到内存。运行时数据区(Runtime Data Area):JVM 核心内存空间结构模型。执行引擎(Execution Engine…

鸿蒙和安卓,到底有什么区别?

对于开发者来说两个最关键的点值得关注:一个是 Beta 版的开发工具,一个是开源网站。开源网站在开发者大会上宣布将 HarmonyOS源代码捐赠给中国开放原子开源基金会,并在大会上公布了鸿蒙系统的开源路线。OpenHarmony 官方源码地址:…

错题集03

(选择一项) 3A: B: C: D: 正确答案是 B解析:LinkedList是实现List,Collection接口,是链表方式进行构建的,根据开发要求不同,可以使用LinkedList实现栈(先进先出)和堆(先进后出)这样的数据结构。(选择一项) 4A: B: C: D: 正确答案是 C解析:由于Hashtable是线程…

项目管理基础:软件开发的方法介绍

软件开发方法主要有结构化方法、原型化方法、面向对象开发方法、敏捷方法。1、结构化方法结构化方法由结构化分析、结构化设计、结构化程序设计组成,它是一种面向数据流的开发方法。结构化分析:依据分解与抽象的原则,按照系统中数据处理的流程…

类加载器子系统的作用

类加载器子系统的作用

Magento Block设计分析(深入分析)

Magento中Block是一个很重要的组件,它在Block中充当非常重要的角色,下面我们来分析一下Magento中Block是怎样设计的,我们应该怎样使用这个重要的角色。1、Magento Block类图: 图1: 继承Varien_Object的对象都有一个_data类变量,用…

JAVA输出x和y和z_JAVA实例:输入三个整数x,y,z,请把这三个数由小到大输出-吾爱编程网...

今天为大家分享一个java经典实例输入三个整数x,y,z,请把这三个数由小到大输出,相信很多初学者都会学到这道题目,接下来吾爱编程为大家介绍一下程序的相关写法,有需要的小伙伴可以参考一下:1、题目:输入三个整数x,y,z,请…

软件项目管理相关概念介绍笔记

1、成本估算由于软件项目具有可见性差、难定量化的特点,一般情况下很难在项目完成前准确的评估软件项目开发的工作量和费用。通常会根据以往开发类似项目的经验来进行成本估算。也可以将整个项目划分为若干个子系统或按照软件的生命周期的各个阶段分别进行费用估算&…

类加载器ClassLoader的角色

类加载器ClassLoader的角色

软件项目管理:进度管理相关概念介绍

软件项目管理当中,项目进度的合理安排是如期完成软件项目的重要基础,也是合理分配资源的重要依据。项目进度安排是项目管理工作当中非常重要的组成部分。软件开发项目进度安排的方式:1、系统最终交付日期已经确定,软件开发部门必须…

ios开发 多人语音聊天_手游语音市场的现状、机遇与挑战

文/手游那点事小鱼原创2014年持续火热的手游市场成就了一大批企业的上市梦,同时也在大环境下产生了对系列手游增值服务的需求。基于玩家对手游社交性的需求,以及借鉴传统端游,页游中成功的社交体系,手游市场逐步出现了对手游语音的…