JavaScript变量提升的本质
变量提升
先说三句总结性的话:
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变量提升的本质的更多相关文章
- javascript变量提升详解
js变量提升 对于大多数js开发者来说,变量提升可以说是一个非常常见的问题,但是可能很多人对其不是特别的了解.所以在此,我想来讲一讲. 先从一个简单的例子来入门: a = 2; var a; cons ...
- 回归基础: JavaScript 变量提升
from me: javascript的变量声明具有hoisting机制,它是JavaScript一个基础的知识点,也是一个比较容易犯错的点,平时在开发中,大大小小的项目都会遇到. 它是JavaScr ...
- JavaScript变量提升 面试题
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- JavaScript变量提升和函数声明预解析
1.首先理解函数作用域 在JavaScript中,变量的定义并不是以代码块作为作用域的,而是以函数作用作用域的.也就是说,如果变量是在某个函数中定义的,那么它在函数以外的地方是不可见的.而如果该变量是 ...
- javascript变量提升
提升是一种将变量和函数的声明移到函数作用域(如果不在任何函数内的话就是全局作用域)最顶部的机制. 提升影响了变量的生命周期,一个变量的生命周期包含3个阶段: 声明——创建一个新变量,例如var myV ...
- 最通俗易懂的javascript变量提升
a = 'ghostwu'; var a; console.log( a ); 在我没有讲什么是变量提升,以及变量提升的规则之前, 或者你没有学习过变量提升,如果按照现有的javascript理解, ...
- JavaScript 变量提升
变量提升(Hoisting):在ES6之前,函数声明和变量声明总是被JavaScript解释器隐式地提升(hoist)到包含他们的作用域的最顶端. 注意: 1. JavaScript 仅提升声明,而不 ...
- 160622、详解JavaScript变量提升
变量在程序中随处可见.它们是一些始终在相互影响,相互作用的的数据和逻辑.正是这些互动使应用程序活了起来. 在JavaScript中使用变量很重要的一方面就是变量的提升 —— 它决定了一个变量何时可以被 ...
- 详解JavaScript变量提升
变量在程序中随处可见.它们是一些始终在相互影响,相互作用的的数据和逻辑.正是这些互动使应用程序活了起来. 在JavaScript中使用变量很重要的一方面就是变量的提升 —— 它决定了一个变量何时可以被 ...
随机推荐
- 洛谷P3796 - 【模板】AC自动机(加强版)
原题链接 Description 模板题啦~ Code //[模板]AC自动机(加强版) #include <cstdio> #include <cstring> int co ...
- Activity的生命周期& 启动模式
1.Activity的生命周期 生命周期这个事情,是android工程师最基础的知识,所以今天要讲的是一些不一样的东西. 1.1 OnStart,OnResume,OnPause,OnStop 他们的 ...
- 如何高效的编写Verilog HDL——进阶版
博主之前写过一篇文章来谈论如何高效的编写Verlog HDL——菜鸟版,在其中主要强调了使用Notepad++来编写Verilog HDL语言的便捷性,为什么说是菜鸟版呢,因为对于新手来说,在还没有熟 ...
- dwr3+spring实现消息实时推送
最近项目要实现一个消息推送的功能,主要就是发送站内信或者系统主动推送消息给当前在线的用户.每次的消息内容保存数据库,方便用户下次登录后也能看到.如果当前用户在线,收到站内信就主动弹出提示.一开始想到的 ...
- win10 , JAVA安装 环境搭建
一.关于下载地址及方式: 1.百度搜索JDK,进入下载官网,具体网址如下: click me!!! 2.根据你电脑的不同系统选择对应的下载,当然首先你要点击Accept License Agreeme ...
- Hibernate入门这一篇就够了
前言 本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门,相信你们看了就会使用Hibernate了! 什么是Hibernate框架? Hibernate是一种ORM框架,全 ...
- dm642的中断定时器
TIMER_Handle TimerHandle0; void timer1() { ////////////定时器/////////////////////// TimerHandle0 = TI ...
- [php错误]PHP中Notice: unserialize(): Error at offset of bytes in on line 的解决方法
使用unserialize函数将数据储存到数据库的时候遇到了这个报错, 后来发现是将gb2312转换成utf-8格式之后, 每个中文的字节数从2个增加到3个之后导致了反序列化的时候判断字符长度出现了问 ...
- Java中private、protected和public作用域的异同
Java中private.protected和public作用域的异同 说明:(1)private的作用范围为当前类,protected的作用范围哦不能超过其他包: (2)区别不同的作用域的不同作用范 ...
- freemarker获取封装类中对象的属性
freemarker获取封装类中对象的属性 1.设计思路 (1)封装学生类 (2)创建数据模型 (3)新建student.ftl (4)运行Junit测试文件,生成HTML文件 2.封装学生类 Stu ...