js中的变量提升和函数提升

js中的变量提升和函数提升

在js中在声明变量或者函数时,会将变量或者函数的创建或者初始化放在代码最顶端,而赋值过程仍在原地,这就是变量提升(函数提升);它并不是物理层面的代码移动,而是在编译时,会先放到内存中去。

var let const声明变量的区别

在ES6中新增了let和const两中声明变量的方式,那么它们和var相比较到底有什么区别呢?
首先我们先知道两点:(1)var和let是变量,const是常量。(2)var没有块级作用域,let和const有块级作用域。

// 使用 var
for (var i = 0; i < 10; i++) {
    var j = i + 1
}
console.log(i,j) // 结果: 10 10

// 使用let
for (let i = 0; i < 10; i++) {
    let j = i + 1
}
console.log(i,j) // 结果: ReferenceError: i is not defined

以上代码就可以看出,let只在代码块以内有效,而var不是。

var声明变量的变量提升

var在声明变量时,分别会经历三个过程:创建(在内存中创建变量)->初始化(将变量初始化为undefined)->赋值(为变量进行赋值)。那么在这三个过程中,究竟是什么时候进行了变量提升。

// var 变量提升
console.log(a) //结果: undefined
var a = 100
// 执行过程
// 1.创建变量 a (提升了)
// 2.初始化变量 a 为 undefined(提升了)
// 3.打印 a 此时它为 undefined
// 将 a 赋值为 100

以上代码其打印结果为undefined也就是说它被初始化了而没有赋值,所以var声明变量的时候,创建和初始化被提升了,而赋值过程没有被提升。我们也可以把以上代码当作是下面这样子:

// 相当于以下代码
var a // 创建和初始化
console.log(a) // 结果: undefined
a = 100 // 赋值

let声明变量的变量提升

let在声明变量时,同样有三个过程创建->初始化->赋值,基于此我们来看一看let在声明过程的变量提升。

// let 变量提升
console.log(a) // 结果:ReferenceError: a is not defined
let a = 100

直接报错了,我们无法使用一个未初始化的数据,也就是说let在声明变量时,初始化过程并未被提升,后面的赋值过程并不会执行。我们在看一段代码

let a = 100
!(function () {
    console.log(a) // 结果:ReferenceError: a is not defined
    let a = 200
})()

在这段代码中,并没有输出100,这是因为在下面的块作用域里面,a被创建了,所以js会优先使用当前作用域的a,但是我们已经知道并没有初始化,所以会报错。
由此我们就知道let在声明变量时,创建过程被提升了,初始化和赋值过程没有被提升。

const声明变量的变量提升

const 和 let 是的变量提升是一样的,但是有一个区别就是,const是常量,不可被修改,所以没有赋值过程。

声明函数的函数提升

我们分别进行函数声明和字面量声明的方式分别看看函数提升。

// 函数声明方式--function
console.log(foo) // 结果: [Function: foo]
function foo () {
    return '你好'
}

// 字面量声明方式--var
console.log(foo) // 结果: undefined
var foo = function () {
    return '你好'
}

// 字面量声明方式--let
console.log(foo) // 结果: ReferenceError: foo is not defined
let foo = function () {
    return '你好'
}

// 字面量声明方式--const
console.log(foo) // 结果: ReferenceError: foo is not defined
const foo = function () {
    return '你好'
}

由以上代码可以看出,使用function的函数声明方式,创建、初始化、和赋值都被提升了。而使用字面量方式声明函数的话,和上面讲的var let const的变量声明的变量提升保持一致。

总结

  1. var声明变量的时候,创建和初始化被提升了,而赋值过程没有被提升。
  2. let和const在声明变量时,创建过程被提升,但是初始化过程并未被提升,另外let有赋值过程而const没有。
  3. 使用function的函数声明方式,创建、初始化、和赋值都被提升了。而使用字面量方式声明函数时,和var let const的变量声明的变量提升保持一致。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值