js 中的变量提升

变量提升

因为var不管写在哪里,都会被提升到作用域顶端。

var声明变量会导致变量提升。变量声明后赋值前都是undefined。

console.log(aa);//undefined

var aa = "11"

console.log(aa)//报错

let aa = "11"

函数变量提升

在函数内部的变量也存在变量提升。

function(){

console.log(aa)

var aa = "11";

}

等价于

function() {

var aa

console.log(aa)

aa = "11"

}

函数提升

fn()// fn is not function

// 变量式声明

var fn = function() {

console.log("11")

}

//函数式声明

fn();// 11

function fn() {

console.log("11")

}

变量式声明方法和声明变量一样fn=undefined, 函数式声明方法会将方法和其中的内容提升到作用域最前面。

为什么会有变量提升

javascript要经历编译和执行两个阶段,编译阶段会搜寻收集所有的声明,剩下的语句在执行阶段会逐句生效。所以就有了var声明的变体会首先被赋值undefined。

想了解变量提升首先要知道什么是作用域。作用域是函数和变量的可访问范围,作用域控制着变量和函数的范围和生命周期。

es6之前作用域分为两种,全局作用域 函数作用域。全局作用域作用域全局,其生命周期随着页面的生命周期,函数作用域作用域函数内部。函数被访问时访问。函数执行结束后函数内部定义的变量会被销毁。

变量提升的好处

性能优化;javascript在执行之前,首先会进行语法检查和预编译(这个操作只会执行一次),预编译的时候会收集所有的声明函数和声明变量,这样就不会每次执行前去重新解析变量和函数(变量和函数一旦声明就不会改变,多次解析影响性能)。

Js在预编译的时候会给统计声明的变量和函数,同时会压缩函数,去除注释及空白,使的每次执行时可以直接给函数分配栈空间。不需要重复执行。

同时也会提高容错行比如下面的代码就不会报错,且能正常 执行。

a=“1”;

var a;

console.log(a)// “1”;

变量提升的弊端

变量名冲突案例:

Var name = “javascript”

Function showName() {

console.log(name)

If(0) {

Var name = “abc"

}

}

showName()//undefined

为什么是undefined?

当有两个同名的变量声明在同一个作用域中执行最下面的变量,当变量在不同作用域中,变量执行当前作用域里的变量,所以上面打印的是函数中的变量name但因为函数中的name存在变量提升,所以name的值undefined。(如果是C语言的话这里输出的是全局变量)

变量未被销毁的案例

function foo() {

For(var i=0; i<5; i++){}

console.log(i);

}

Foo()// 5

Foo结束的时候i并没有被销毁,同时i的变量被提升,所以输出是i的最终结果5.

禁止变量提升

为什么禁止变量提升

避免项目中因为忘记声明的变量以undefined的形式存在,防止undefined带来的不可预知的问题。

es6中引入了let和const语法,let和const声明的变量只作用于块级作用域中。块级作用域内声明的变量不会影响块外面的变量。

js如何支持块级作用域

预编译阶段统计所有声明var声明的变量执行比变量环境,即为给var声明的变量赋值undefined。块级作用域声明的变量执行词法环境,词法环境下声明的变量没有默认值,且在赋值前调用回报错。(在函数作用域中块级作用域中声明的变量并不走词法环境)

词法环境回根据不同的块级作用域生成对应栈,块级作用域就是通过词法环境的栈来实现的,变量提升是变量环境实现的。所以通过词法环境的栈和环境变量混合使用就同时支持了var声明和块级作用域。

暂时性死区

使用let或const声明变量后变量会在块级作用域中被声明,到变量被赋值之前,这段时间叫暂时性死区,在变量属于暂时性死区是调用变量,就回报错。这时候的typeOf是不准确的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值