变量提升

先说三句总结性的话:

  • 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);

打印结果:

代码 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);
}

打印结果:

代码 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);

打印结果:

声明时的重名问题

假设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)

打印结果:

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

提醒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);

打印结果:

1

2

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

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

JavaScript变量提升的本质的更多相关文章

  1. javascript变量提升详解

    js变量提升 对于大多数js开发者来说,变量提升可以说是一个非常常见的问题,但是可能很多人对其不是特别的了解.所以在此,我想来讲一讲. 先从一个简单的例子来入门: a = 2; var a; cons ...

  2. 回归基础: JavaScript 变量提升

    from me: javascript的变量声明具有hoisting机制,它是JavaScript一个基础的知识点,也是一个比较容易犯错的点,平时在开发中,大大小小的项目都会遇到. 它是JavaScr ...

  3. JavaScript变量提升 面试题

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  4. JavaScript变量提升和函数声明预解析

    1.首先理解函数作用域 在JavaScript中,变量的定义并不是以代码块作为作用域的,而是以函数作用作用域的.也就是说,如果变量是在某个函数中定义的,那么它在函数以外的地方是不可见的.而如果该变量是 ...

  5. javascript变量提升

    提升是一种将变量和函数的声明移到函数作用域(如果不在任何函数内的话就是全局作用域)最顶部的机制. 提升影响了变量的生命周期,一个变量的生命周期包含3个阶段: 声明——创建一个新变量,例如var myV ...

  6. 最通俗易懂的javascript变量提升

    a = 'ghostwu'; var a; console.log( a ); 在我没有讲什么是变量提升,以及变量提升的规则之前, 或者你没有学习过变量提升,如果按照现有的javascript理解, ...

  7. JavaScript 变量提升

    变量提升(Hoisting):在ES6之前,函数声明和变量声明总是被JavaScript解释器隐式地提升(hoist)到包含他们的作用域的最顶端. 注意: 1. JavaScript 仅提升声明,而不 ...

  8. 160622、详解JavaScript变量提升

    变量在程序中随处可见.它们是一些始终在相互影响,相互作用的的数据和逻辑.正是这些互动使应用程序活了起来. 在JavaScript中使用变量很重要的一方面就是变量的提升 —— 它决定了一个变量何时可以被 ...

  9. 详解JavaScript变量提升

    变量在程序中随处可见.它们是一些始终在相互影响,相互作用的的数据和逻辑.正是这些互动使应用程序活了起来. 在JavaScript中使用变量很重要的一方面就是变量的提升 —— 它决定了一个变量何时可以被 ...

随机推荐

  1. Photoshop CC 常用快捷方法有哪些?

    Photoshop CC 常用快捷方法有哪些? 属性栏 工具栏 控制面板 绘图区 1. 多个图层如何快速居中? 在 控制面板 中选中多个图层创建 链接图层 在 工具栏 选择 移动工具 在 属性栏 点击 ...

  2. linux_group总结

    group_name:passwd:GID:user_list 在/etc/group 中的每条记录分四个字段: 第一字段:用户组名称: 第二字段:用户组密码: 第三字段:GID 第四字段:用户列表, ...

  3. 左连接条件与where条件的区别

    Sql 查询语句应用左连接时的链接条件中经常加一些常量值在里面如: "On a.id= b.id and b.is_del =0 and b.is_old =1" 这种条件如果加在 ...

  4. 【前端】用百度BAE和express部署自己的node后台

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/node_bae.html 百度有一个应用引擎,价格非常便宜,Java的tomcat每天4毛钱,node每天2毛钱, ...

  5. 追溯 React Hot Loader 的实现

    文:萝卜(沪江金融前端开发工程师) 本文原创,转载请注明作者及出处 如果你使用 React ,你可以在各个工程里面看到 Dan Abramov 的身影.他于 2015 年加入 facebook,是 R ...

  6. PaddlePaddle︱开发文档中学习情感分类(CNN、LSTM、双向LSTM)、语义角色标注

    PaddlePaddle出教程啦,教程一部分写的很详细,值得学习. 一期涉及新手入门.识别数字.图像分类.词向量.情感分析.语义角色标注.机器翻译.个性化推荐. 二期会有更多的图像内容. 随便,帮国产 ...

  7. 关于echarts

    昨天随手玩了下echarts,看见同事纠结于echarts的兼容问题. 最简单的echarts(官网的): <div id="main" style="width: ...

  8. 使用CXF和spring搭建webService服务

    虽然下一个项目需要使用xfire,但是在查资料的过程中还是看到有不少地方都说cxf比xfire更好,cxf继承了xfire,但是不仅仅包含xfire,因此便也一起来尝试尝试.大概是有了xfire的经验 ...

  9. My97DatePicker日历控制按日、按周和按月选择

    My97DatePicker日历控制按日.按周和按月选择 1.设计源码 <%@ page language="java" import="java.util.*&q ...

  10. AM335x(TQ335x)学习笔记——触摸屏驱动编写

    前面几篇文章已经通过配置DTS的方式完成了多个驱动的移植,接下来我们解决TQ335x的触摸驱动问题.由于种种原因,TQ335x的触摸屏驱动是以模块方式提供的,且Linux官方内核中也没有带该触摸屏的驱 ...