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

2018-09-16 admin

在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://segmentfault.com/a/1190000016416430

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-40432.html

文章标题:JS中的变量提升和函数提升

相关文章
React.js编程思想
JavaScript框架层出不穷,在很多程序员看来,React.js是创建大型、快速的Web应用的最好方式。这一款由Facebook出品的JS框架,无论是在Facebook还是在Instagram中,它的表现都非常出色。 使用React.j...
2015-11-12
Vue获取DOM元素样式和样式更改示例
在 vue 中用 document 获取 dom 节点进行节点样式更改的时候有可能会出现 ‘style’ is not definde的错误,这时候可以在 mounted 里用 $refs 来获取样式,并进行更改: <template...
2017-03-13
从2014年的发展来展望JS的未来将会如何
<font face="寰�杞�闆呴粦, Arial, sans-serif ">2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
Vue.js组件tab实现选项卡切换
本文实例为大家分享了vue插件tab选项卡的具体代码,供大家参考,具体内容如下 效果图: 代码如下: <!DOCTYPE html> <html lang="en"> <head> ...
2017-03-13
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
three.js实现围绕某物体旋转
话不多说,请看代码: 可以拖动右上角观察变化 <!DOCTYPE html> <html lang="en" style="width: 100%; height:100%;"&gt...
2017-02-17
NodeJS参考手册pdf版
下载地址:Nodejs参考手册PDF版下载 ...
2015-11-12
Node.js学习(1)----HTTP服务器与客户端
Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端。http.Server 是一个基于事件的 HTTP 服务器,它的核心由 Node.js 下层 C++部分实现,而接口由 Jav...
2015-11-12
Riot.js:不足1KB的MVP客户端框架
Riot.js是一款MVP(模型-视图-呈现)开源客户端框架,其最大的特点就是体积非常小,不足1KB,虽然体积小,但它可以帮助用户构建大规模的Web应用程序。 Riot.js是由Moot公司开发,目前最新版本为v0.9.2,遵循MIT开源许...
2016-03-11
typeof、instanceof和contructor的区别
typeof:以字符串的形式返回变量的原始类型,typeof在两种情况下会返回"undefined":一个变量没有被声明的时候,和一个变量的值是undefined的时候,注意,typeof null也会返回object,...
2015-11-12
回到顶部