14

JS变量提升和函数提升

 3 years ago
source link: http://www.cnblogs.com/hzz-499/p/13773751.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1.变量提升

在ES6之前,我们声明一个变量需要用到var关键字,用var来声明的变量就存在变量提升的特性。

2160975-20201006144939927-1464815867.png

上述代码粗略来讲解,在上述代码中存在全局作用域和函数作用域,在两个作用域中都声明了变量a。在fn函数执行console.log(a)的时候,先会在自身所处在的函数作用域中找到变量a,

如果没有找到,就会去全局作用域中找。

在fn函数作用域中我们可以看到a变量声明并赋值了,但是它处于console.log(a)语句的下方,按照正常的逻辑,它不应该找到的是外层定义的a吗?但是结果恰恰相反。

代码执行流程:

我们可以根据位置来把代码分为全局代码和函数(局部)代码。在执行全局代码前,首先将window添加为全局执行上下文,之后对全局数据做预处理工作:

(1)找到var关键声明的变量,赋值为undefined,且添加为window的属性。=>变量提升

(2)将function声明的变量赋值fun(),添加为window属性。=>函数提升

(3)this =>赋值window

在预处理结束后,开始执行全局代码。

函数代码执行流程也和上述大同小异,这里涉及到执行上下文,就不细讲了,后续会补充。

所以我们可以这样理解这行代码

2160975-20201006153126752-176111603.png

最后的结果自然就是undefined。这就是js存在的 变量提升

2.函数提升

函数提升和变量提升的原理一样,区别就是在于,函数提升已经创建好了函数对象,而变量提升赋值为undefined,可以理解为变量声明提升。

2160975-20201006160745693-1497438445.png

2160975-20201006160833465-2057923056.png

3.拓展

( 1) var fn = function(){}和function fn(){}的区别: 前者为变量提升,后者为函数提升。

2160975-20201006161430066-1633078351.png

2160975-20201006161417770-184167397.png

如果是用变量提升来声明函数,如果在此前调用该函数,此时的函数对象并没有创建,变量fn2赋值为undefined,所以浏览器不能识别,把它当做函数来调用,所以最后报错。

(2)在js中,函数是第一公民

被覆盖的不是函数fn,而是var fn =3;

2160975-20201006162819441-1556851894.png

结果:

2160975-20201006162949544-1382530500.png

loading.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK