博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript变量提升的理解
阅读量:6720 次
发布时间:2019-06-25

本文共 2219 字,大约阅读时间需要 7 分钟。

变量提升

先说三句总结性的话:

  • let 的「创建」过程被提升了,但是初始化没有提升。

  • var 的「创建」和「初始化」都被提升了。

  • function 的「创建」「初始化」和「赋值」都被提升了。

所以,我们要注意,这三种变量提升,含义是不同的。

变量提升的规律

在进入一个执行上下文后,先把 var 和 function 声明的变量前置,再去顺序执行代码。

PS:作用域分为全局作用域和函数作用域,用var声明的变量,只在自己所在的所用域有效。

我们举例来看看下面的代码。

代码 1:

console.log(fn);    var fn = 1;    function fn() {    }    console.log(fn);

相当于:

var fn = undefined;    function fn() {    }    console.log(fn);    fn = 1;    console.log(fn);

打印结果:

20180321_1810.png

代码 2:

console.log(i);    for (var i = 0; i < 3; i++) {        console.log(i)    }

相当于:

var i = undefined;    console.log(i);    for (i = 0; i < 3; i++) {        console.log(i);    }

打印结果:

20180321_1817.png

代码 3:

var a = 1;    function fn() {        a = 2;        console.log(a)        var a = 3;        console.log(a)    }    fn();    console.log(a);

相当于:

var a = undefined;    function fn() {        var a        a = 2        console.log(a)        a = 3        console.log(a)    };    a = 1;    fn();    console.log(a);

打印结果:

20180321_1827.png

声明时的重名问题

假设a被声明为变量,紧接着a又被声明为函数,原则是:声明会被覆盖(先来后到,就近原则)。

PS:

  • 如果a已经有值,再用 var 声明是无效的。

  • 如果a已经有值,紧接着又被赋值,则赋值会被覆盖

举例1:

var fn;  //fn被声明为变量    function fn() {// fn被声明为function,就近原则    }    console.log(fn); //打印结果:function fn(){}

举例2:

function fn() {}  //fn被声明为function,且此时fn已经被赋值,这个值就是function的对象    var fn;   //fn已经在上一行被声明且已经有值, 再 var 无效,并不会重置为 undefined    console.log(fn)  //打印结果:function fn(){}

既然再var无效,但是再function,是有效的:

function fn() {}  //fn被声明为function,且此时fn已经有值,这个值就是function的对象    function fn() {   //此时fn被重复赋值,会覆盖上一行的值        console.log('smyhvae');    }    console.log(fn)

打印结果:

20180321_1845.png

函数作用域中的变量提升(两点提醒)

提醒1:

在函数作用域也有声明提前的特性:

  • 使用var关键字声明的变量,是在函数作用域内有效,而且会在函数中所有的代码执行之前被声明

  • 函数声明也会在函数中所有的代码执行之前执行

因此,在函数中,没有var声明的变量都会成为全局变量,而且并不会提前声明。

举例1:

var a = 1;        function foo() {            console.log(a);            a = 2;     // 此处的a相当于window.a        }        foo();        console.log(a);   //打印结果是2

上方代码中,foo()的打印结果是1。如果去掉第一行代码,打印结果是Uncaught ReferenceError: a is not defined

提醒2:定义形参就相当于在函数作用域中声明了变量。

function fun6(e) {            console.log(e);        }        fun6();  //打印结果为 undefined        fun6(123);//打印结果为123

其他题目

var a = 1;    if (a > 0) {        console.log(a);        var a = 2;    }    console.log(a);

打印结果:

12

上方代码中,不存在块级作用域的概念。if语句中用var定义的变量,仍然是全局变量。

顺便延伸一下,用let定义的变量,是在块级作用域内有效。

转载地址:http://kacmo.baihongyu.com/

你可能感兴趣的文章
redhat6.0安装步骤
查看>>
央视广告招标京东成黑马 茅台是标王
查看>>
CnetOS 6.6 rsync 的服务端和客户端配置
查看>>
mysql双主同步配置
查看>>
【拾贝】版本控制-git 建立Team项目
查看>>
和为S的连续正数序列
查看>>
孩子们的游戏(圆圈中最后剩下的数)
查看>>
MySQL的AB复制
查看>>
Mysql调优:
查看>>
批量修改root密码#shell脚本
查看>>
Linux命令学习记录(四)
查看>>
Oracle日常维护操作笔记(一)
查看>>
网管必懂的几个概念
查看>>
puppet 部署
查看>>
ISCSI文件存储
查看>>
求助:关于windows飞信机器人的问题
查看>>
我的友情链接
查看>>
关于初步搭建完成SSH环境之后,JUnit test 测试成功,页面测试时:@Resource 注入的dao为null...
查看>>
更强大的 code generator 自定义工具
查看>>
PHP 在大多数 Unix 平台
查看>>