关于JS的变量提升和函数提升

1、变量提升  

  首先,ES6有一些新的特性,比如说引入了let来定义变量,let和原先的var相比,有一些不同的地方,首先就是let不存在变量提升了,我当时对变量提升有点懵,搞不清楚什么是变量提升,后来才慢慢的搞清楚,变量提升就是把变量声明提升到当前执行环境的最顶端。

先来两段代码比较一下:  

    var a;
    a = 123;
    console.log(a);

这个当然非常简单,就是定义了一个变量,给其赋值,然后输出,那看下面这个

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

//相当于
var foo;  //声明且初始化为undefined
console.log(foo);
foo=2;

这中情况在函数中也是一样的

function test () {
    var a;
    console.log(a);  //也是打印undefined
    a = 123;
}
test();

这个就是典型的变量提升了,在console.log之前,没有变量的定义,但是他的下面有一个var foo=2,这个时候,浏览器的机制会把这些定义赋值的变量都放到最上面去先定义,而且是空的,既然是空的,所以打印的foo当然是undefined,然后打印完了之后才给这个foo赋值,这就是变量的提升,这样简单的情况可能清晰一点,但是放到比较复杂的函数中可能就会混淆了。

下面来看一道题:

console.log(a);
var a = 100;
function foo() {
    console.log(a);
    var a = 200;
    console.log(a);
}
foo();
console.log(a);

输出的结果:

//undefined
//undefined
//200
//100

第一个自然就是变量提升没有赋值打印undefined了,第二个在函数中和函数外的那个一样,在这个函数的作用域中也存在了一个变量提升,所以也是undefined,第三个就是正常打印出函数中的局部变量了,所以是200。最后一个是因为作用域的关系,打印的上面的全局变量,所以是100.

ES6中的let如果也这么写,是不打印undefined的,会直接报错。

console.log(a); // 报错ReferenceError
let a= 2;
//相当于在第一行先声明a但没有初始化,直到赋值时才初始化
let a;
console.log(a);
a = 2;

 虽然看起来也是先定义了没赋值,但是在ES6中,console.log的时候,a没有初始化,在a被赋值之前会产生暂时性死区,在这中间是不能对a进行调用的。这也是相较于var,let更优秀的一点,可以避免很多错误,效率也会得到提升。

    借别人的话总结一下:我们习惯将var a = 2;看做是一个声明,而实际上javascript引擎并不这么认为。它将var a和a = 2看做是两个单独的声明,第一个是编译阶段的任务,而第二个则是执行阶段的任务。

2、函数提升

  除了变量可以提升,函数也是可以提升的,函数声明提升就是直接把整个函数提到执行环境的最顶端。而且,在考虑这方面的时候,一定要记住,函数提升要优于变量提升,也就是函数优先原则。

 函数声明分为两种:

//函数声明式
function foo () {}


//函数字面量式 
var foo = function () {}

 

函数字面量式的函数提升就类似于变量的函数提升

    foo();
    
    var foo = function(){
        console.log("aaa");
    }
var foo;
console.log(foo);  //undefined
foo(); //foo is not a function
 foo = function(){
        console.log("aaa");
    }

这个结果就是undefined,本质还是变量提升

函数声明式有些不同,函数声明式的函数提升就是把函数放到了执行环境的最上面

    console.log(foo);
    
    function foo(){
        console.log(10);
    }

结果就是打印:

ƒ foo(){
        console.log(10);
    }

因为存在函数提升,把函数放到了最上面,然后再进行变量提升,相当于:

function foo(){
        console.log(10);
    }
var foo;
console.log(foo);

至于为什么会输出函数,是因为下面的var foo并没有赋值,所以打印的是上面的函数。

如果是

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

那打印的就是1了。

希望可以对大家理解变量提升和函数提升有帮助。

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值