资讯专栏INFORMATION COLUMN

深入理解 js 变量提升

venmos / 1732人阅读

摘要:我们知道再中的和的申明都存在又变量提升,中的则不存在有变量提升。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升。深入理解声明的变量的作用域是块级的不能重复声明已存在的变量有暂时死区,不会被提升。

我们知道再ES5中的varfunction 的申明都存在又变量提升,ES6中的 letconst 则不存在有变量提升。

var变量提升

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

// 等价于

var a ;
console.log(a); // undefined
a = 1; 

js中的 function 也可以看作是变量,也存在变量提升

a(); // 1

function a() {
    console.log(1);
}
总之

JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。

let深入理解

let 声明的变量的作用域是块级的;

let 不能重复声明已存在的变量;

let 有暂时死区,不会被提升。

// case1
var liList = document.querySelectorAll("li") // 共5个li
for( var i=0; i

依次点击会出现5个 5 。如果把var 改为了let 就是分别打印0 , 1 , 2, 3, 4 了。

我的理解是:

for(let i = 0; i< 5; i++) 这句话的圆括号之间存在有一个隐藏的作用域

再每次执行循环体的时候都会在循环体上下文中重新初始化一次

var liList = document.querySelectorAll("li") // 共5个li
for( let i=0; i

下面我们再来仔细刨析一下具体声明的过程

var变量声明的创建、初始化和赋值过程

function fn(){
    var a = 0;
    var b = 1;
}

fn();

过程分析:

进入fn,为其创建一个环境

找出fn中所有声明的变量,在这个环境中创建这些变量(a,b)

将这些变量初始化为undefined

开始执行代码

a 赋值 0,b 赋值 1;

这就解释了为什么在 var x = 1 之前 console.log(x) 会得到 undefined。

function的声明的创建、初始化、和赋值过程

f2(); // 2

function f2() {
    console.log(2);
}

过程分析:

找到function声明的变量,在环境中创建

将这些变量初始化并赋值, function(){ console.log(2) }。

开始执行代码 fn(); //2

let声明的创建、初始化、赋值

{
  let x = 1
  x = 2
}

过程分析:

找到let变量在环境中创建,

开始执行代码 ,注意还没有进行初始化哦

执行x = 1; x 初始化为 1

执行x = 2; x 进行赋值

我们再来理解一下let 之前不能使用的原因

{
    console.log(a);
    let a  = 1;
}

原因:

console.log(a) 中的 a 指的是下面的 a,

执行 log 时 x 还没「初始化」,所以不能使用(也就是暂时性死区)

总结

let 的「创建」过程被提升了,但是初始化没有提升。
var 的「创建」和「初始化」都被提升了。
function 的「创建」「初始化」和「赋值」都被提升了。

最后看 const,其实 const 和 let 只有一个区别,那就是 const 只有「创建」和「初始化」,没有「赋值」过程。

所谓暂时死区,就是不能在初始化之前,使用变量。

参考文献

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94263.html

相关文章

  • 深入理解 js 声明提升( 尾部有总结 和 面试题解析 )

    摘要:要理解函数的提升行为,让我们先解析什么是的提升。也就是说声明提升了,赋值还留着原地,等待执行。声明被提升,而包括函数表达式的赋值在内的赋值操作并不会提升,而是留在原地等待执行。 javaScript自上而下执行的顺序受到很多新手和部分老手的共识,但是这其实并不完全正确,这涉及到js的编译过程,这方面我们稍后会聊到,先考虑下面代码: window.onload = function(){...

    curlyCheng 评论0 收藏0
  • 深入理解let和var的区别(暂时性死区)!!!

    摘要:会出现这样的情况是因为拥有暂时性死区。规定暂时性死区和语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。 首先我们应该知道js引擎在读取js代码时会进行两个步骤: 第一个步骤是解释。 第二个步骤是执行。 所谓解释就是会先通篇扫描所有的Js代码,然后把所有声明提升到顶端,第二步是执行,执行就是操作一类的。 我们先来看个简单的变量提升...

    tanglijun 评论0 收藏0
  • 深入理解JavaScript(一):变量提升

    摘要:变量提升原理引擎的工作方式是先解析代码,获取所有被声明的变量然后在运行。代码自上而下执行之前,浏览器首先会把所有带关键词的进行提前声明或者定义,这种预先处理机制称之为变量提升。 变量提升 原理:JS引擎的工作方式是先解析代码,获取所有被声明的变量;然后在运行。JS代码自上而下执行之前,浏览器首先会把所有带 VAR/FUNCTION 关键词的进行提前 声明 或者 定义 ,这种预先处理机制...

    voidking 评论0 收藏0
  • 深入理解JavaScript执行上下文和执行栈

    摘要:执行上下文和执行栈是中关键概念之一,是难点之一。理解执行上下文和执行栈同样有助于理解其他的概念如提升机制作用域和闭包等。函数执行完成,函数的执行上下文出栈,并且被销毁。 前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制。执行上下文和执行栈是JavaScript中关键概念之一,是Ja...

    silenceboy 评论0 收藏0
  • 深入理解JavaScript执行上下文和执行栈

    摘要:执行上下文和执行栈是中关键概念之一,是难点之一。理解执行上下文和执行栈同样有助于理解其他的概念如提升机制作用域和闭包等。函数执行完成,函数的执行上下文出栈,并且被销毁。 前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制。执行上下文和执行栈是JavaScript中关键概念之一,是Ja...

    leiyi 评论0 收藏0

发表评论

0条评论

venmos

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<