资讯专栏INFORMATION COLUMN

JS中的变量提升和函数提升

zhunjiee / 1871人阅读

摘要:什么是函数作用域下的变量提升和函数提升函数作用域中也存在变量提升和函数提升,这个和全局作用域下的情况是一模一样的,就是把作用域想成是全局的就可以了。

在js中有一部分比较难以理解,却也是在笔试过程中很容易考的,那就是变量提升和函数提升的问题,这篇文章我会就变量提升和函数提升的问题拓展一下有关js函数的知识点,包括作用域的问题,后面还会有一些小练习来判断自己是否真的搞懂了。
作用域

在js中作用域分为全局作用域和函数作用域,这里是针对用var声明的变量是全局的,还是只是在函数中可以使用,在es6中新增了两个声明变量的方法,let和var一样,都是声明变量的,不过let是在块级作用域下起作用,const是用来声明常量的,不能进行二次赋值。这里重点是变量提升,就先用var来讲解。

全局作用域 什么是全局作用域?

全局作用域是指在当前的script标签内定义的变量,所有的函数都可以使用,它在打开时创建,关闭时销毁。在全局作用域中有一个全局对象window,window是由浏览器创建的,它里面的方法所有对象都可以使用。

在全局作用域下创建的变量会作为window进行保存,创建的函数会作为window的方法

什么是全局作用域下的变量提升?

终于说到变量提升了,那么什么是全局作用域下的变量提升呢?看一下下面的例子:

        console.log(a);//undefined
        var a = 10;
        console.log(a);//10

由于在js中代码执行的顺序是从上而下,所以在第一次打印的时候,要找变量a,如果没有变量提升的话应该会会报错说a没有定义,而这里输出的是undefined,说明a已经定义了,但是没有赋值。那么这就是变量提升起了作用了。需要注意的是

变量提升只会提升声明,而不会提升赋值,也就是说在执行第一个打印操作时,只是存在变量a,a却没有值;

打印结果是undefined说明变量存在,只是没有值,而如果是报错说a is not defined的话,就是没有变量a。

什么是全局作用域下的函数提升?

函数提升和变量提升是一样的道理,都是将本来应该在后面执行的代码全部放在前面,只是变量提升是提升声明;而函数提升是提升整个函数,也就是在代码还没开始执行的时候函数就会被创建。

调用在定义函数之后
        console.log(a);//undegfined
        var a = 10;
        function fun(){
            console.log(a);
        }
        fun();//10   

这里函数调用是在定义函数之后,看不出来函数是否存在提升的情况,但这里值得一提的是,如果函数没有需要访问的变量的时候,就会去上一层找,就是这个全局的a,值是10,所以会打印10.

调用在定义函数之前
        console.log(a);//undefined
        fun();//undefined
        var a = 10;
        function fun(){
            console.log(a);
        }
           

这里函数调用是在定义函数之前,并且是在a赋值之前。首先我们来判断一下,如果没有函数提升的话会怎样,执行到fun这一行,就会发现fun没有定义,然后会报错fun is not a function;现在有了函数提升过后,执行到fun后,会去找a,而a只是定义了没有赋值,就会打印一个undefined,和第一个打印一样的结果。

函数作用域 什么是函数作用域?

函数作用域,顾名思义,就是只在函数中能够使用的变量,函数作用域和全局作用域之间的关系是函数作用域中的方法可以使用全局的变量,而全局方法不能使用函数中的便来变量,每个函数之间也是不能取到各自函数内部的值的。下面的图帮助理解一下:

每个函数作用域是相互独立的,在函数内部定义的变量是不能进行相互调用的。

什么是函数作用域下的变量提升和函数提升?

函数作用域中也存在变量提升和函数提升,这个和全局作用域下的情况是一模一样的,就是把作用域想成是全局的就可以了。

练习
        var a = 123;
        function fun(){
            alert(a);//123
        }
        fun();
        var a = 123;
        function fun(){
            alert(a);//456
            var a = 456;
        }
        fun();
        alert(a);//123
        var a = 123;
        function fun(){
            alert(a);//123
            a = 456;
        }
        fun();
        alert(a);//456(456是因为函数内部将全局的变量a的值改变了)
        var a = 123;
        function fun(a){
            alert(a);//123
            a = 456;
        }
        fun(123);
        alert(a);//456
 var a = 123;
        function fun(a){
            alert(a);//undefined(undefined是因为fun在被调用的时候没有传递实参)
            a = 456;
        }
        fun();
        alert(a);//456
总结

在面试的笔试题中很容易碰到这样的题,有的可能还不只是考这个知识点,可能还会涉及到闭包之类的,或者更难以理解一点儿的this指向问题,但是不管怎样,只要知道原理,怎么考都没关系,愿大家在前端这段路上坚持走下去,加油!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97812.html

相关文章

  • js 变量提升闭包理解

    摘要:变量的作用域无非就是两种全局变量和局部变量。其中内部函数中可以访问外部函数的变量,是因为内部函数的作用域链中包含了外部函数的作用域也可以理解为内部函数的作用范围辐射到了外部函数的作用范围另一方面,在函数外部自然无法读取函数内的局部变量。 以前学习的时候,了解过变量提升和闭包,但是没有深入了解,网上查了资料,这里记录下,只供参考。部分内容引用: https://www.cnblogs.c...

    luoyibu 评论0 收藏0
  • 原型模式故事链(4)--JS执行上下文、变量提升函数声明

    摘要:代码在执行之前会先全局中变量提升函数声明。函数的执行上下文,也就是在这个函数范围内找到函数执行上下文中函数范围内,所有用声明的变量。函数执行时,按照执行位置查找变量作用域只会向上查找。下一回变量作用域与闭包 上一章:JS的数据类型 传送门:https://segmentfault.com/a/11... 好!话不多少,我们就开始吧。对变量提升和函数声明的理解,能让你更清楚容易的理解,...

    melody_lql 评论0 收藏0
  • 原型模式故事链(4)--JS执行上下文、变量提升函数声明

    摘要:代码在执行之前会先全局中变量提升函数声明。函数的执行上下文,也就是在这个函数范围内找到函数执行上下文中函数范围内,所有用声明的变量。函数执行时,按照执行位置查找变量作用域只会向上查找。下一回变量作用域与闭包 上一章:JS的数据类型 传送门:https://segmentfault.com/a/11... 好!话不多少,我们就开始吧。对变量提升和函数声明的理解,能让你更清楚容易的理解,...

    zhigoo 评论0 收藏0
  • 原型模式故事链(4)--JS执行上下文、变量提升函数声明

    摘要:代码在执行之前会先全局中变量提升函数声明。函数的执行上下文,也就是在这个函数范围内找到函数执行上下文中函数范围内,所有用声明的变量。函数执行时,按照执行位置查找变量作用域只会向上查找。下一回变量作用域与闭包 上一章:JS的数据类型 传送门:https://segmentfault.com/a/11... 好!话不多少,我们就开始吧。对变量提升和函数声明的理解,能让你更清楚容易的理解,...

    netScorpion 评论0 收藏0

发表评论

0条评论

zhunjiee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<