变量提升

先说三句总结性的话:

  • 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变量提升的理解

    废话不说,直接上代码(这是在JavaScript面对对象编程指南上面看到的一个例子) var a=123; function f(){ alert(a); var a=1; alert(a); } f ...

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

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

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

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

  4. JavaScript变量提升 面试题

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

  5. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  6. 对javascript变量提升跟函数提升的理解

    在写javascript代码的时候,经常会碰到一些奇怪的问题,例如: console.log(typeof hello); var hello = 123;//变量 function hello(){ ...

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

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

  8. JavaScript变量提升及作用域

    今天在知乎看前端面试题的时候,看到这样的问题,发现自己懂的真的是太少了,看了给的例子,所以写一下自己的理解. 首先放一段代码: var v= “hello JavaScript”; alert(v); ...

  9. JavaScript: 变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

随机推荐

  1. Ubuntu16.04 + gtx1060 + cuda8.0 + cudnn5.1 + caffe + Theano + Tensorflow

    参考 ubuntu16.04+gtx1060+cuda8.0+caffe安装.测试经历 ,细节处有差异. 首先说明,这是在台式机上的安装测试经历,首先安装的win10,然后安装ubuntu16.04双 ...

  2. [提权]MS16-016提权EXP

    MS16-016提权EXP[K8]Tested On Win7 x86Usage: ms16-016_win7.exe "whoami"by K8拉登哥哥 20160216 下载: ...

  3. 【转】浮点数与IEEE 754

    http://www.cnblogs.com/kingwolfofsky/archive/2011/07/21/2112299.html 浮点数 1.   什么是浮点数 在计算机系统的发展过程中,曾经 ...

  4. Python3自动化运维之Fabric模版详解

    一.概要 Fabric是基于Python(2.7,3.4+以上版本)实现的SSH命令行工具,简化了SSH的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以实现本地或远程shell命令,包括 ...

  5. 使用 Notification API 开启浏览器桌面提醒

    Notifications API 允许网页控制向最终用户显示系统通知 —这些都在顶级浏览上下文视口之外,因此即使用户已经切换标签页或移动到不同的应用程序,也可以显示.该API被设计成与不同平台上的现 ...

  6. 获取 BaiduMapSDKDemo SHA1 签名

    用 Android Studio 1.5 运行 BaiduMapsApiASDemo 时,显示 key 验证出错. 原因在于用 keytool -list -keystore debug.keysto ...

  7. Golang标准库——io-接口

    接口 Read相关 Reader Reader接口用于包装基本的读取方法. type Reader interface { //将数据读入到p中,直到读满p或者读取的过程中遇到错误,此时返回的n< ...

  8. Linux_CentOS-服务器搭建 <五> 补充

    O:文件的编码格式 1.文件转码问题 Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8. 那么先说,如何查看吧.这时候强大的vi说,I can do that.( ...

  9. docker push 出现:x509: certificate signed by unknown authority

    今天,部署生产的程序的时候,出现一个问题:编译正常,但是,docker 把编译好的image 推送到生产环境上去的时候,出现:x509: certificate signed by unknown a ...

  10. 理解运用JS的闭包、高阶函数、柯里化

    JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...