2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > js变量提升_学习笔记:JS中的作用域和预解析

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

时间:2020-08-27 13:44:59

相关推荐

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代码中至少有一个作用域, 即全局作用域。

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

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

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

四.函数和变量提升

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

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

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

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

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

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

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

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

// undefined // undefined // 报错

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

不过结果是

我机智的认为 预想错了?

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

浏览器执行结果:

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

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

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

正确解析顺序是这样的

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

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

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

完美!

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

同名变量

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

同名函数

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

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

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

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

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

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。