You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
包括 var, let 和 const 在内的一切声明都会被“提升”。访问在此之前没申明变量的角度上来说只有 var 才会进行变量提升。let const 会爆出一个错误。而这个错误产生的原因是在于 TDZ (暂时性死区)也是“变量”提升的证明(与其说变量提升不如说是被绑定在此作用域中在未被赋值之前都不能进行访问)。
{console.log(a)// 报错consta=1;}
var 命令在变量的定义被执行之前就初始化变量,并拥有一个默认的 undefined 值。
let 与 const 命令会形成暂时性死区,在变量的定义被执行之前都不会初始化变量,避免在声明语句之前的不正确调用。如果定义时没有给定值的话,let 声明的变量会赋值为 undefined,而 const 声明的变量会报错。
二、函数名提升
(一)函数名也会出现函数提升
func()functionfunc(){console.log('1')}
(二)在变量和函数都有的情况下函数的声明比变量的声明会优先
console.log(a)// function a () { console.log('2') }vara=1functiona(){console.log('2')}
一、变量提升?
什么是变量提升?
你认为这段话会打印什么出来 ? log函数会打印出
1
的结果。这就是变量提升。它使其想当于存在有
var
、let
、const
、隐式声明
这四者都可以声明变量let
、const
、var
这些声明都会将变量的声明进行提升。var
命令在变量的定义被执行之前就初始化变量,并拥有一个默认的undefined
值。let
与const
命令会形成暂时性死区,在变量的定义被执行之前都不会初始化变量,避免在声明语句之前的不正确调用。如果定义时没有给定值的话,let
声明的变量会赋值为undefined
,而const
声明的变量会报错。摘自JavsScript 变量提升和函数提升
注意一下 const 它是一开始就要进行声明和赋值初始化的 其他的特性和 let 差不多。
const 、let 和 var 的主要区别就是前者绑定块作用域后者绑定函数作用域。
Var 的变量提升和 let 的”变量“提升
包括
var
,let
和const
在内的一切声明都会被“提升”。访问在此之前没申明变量的角度上来说只有 var 才会进行变量提升。let const 会爆出一个错误。而这个错误产生的原因是在于 TDZ (暂时性死区)也是“变量”提升的证明(与其说变量提升不如说是被绑定在此作用域中在未被赋值之前都不能进行访问)。var
命令在变量的定义被执行之前就初始化变量,并拥有一个默认的undefined
值。let
与const
命令会形成暂时性死区,在变量的定义被执行之前都不会初始化变量,避免在声明语句之前的不正确调用。如果定义时没有给定值的话,let
声明的变量会赋值为undefined
,而const
声明的变量会报错。二、函数名提升
(一)函数名也会出现函数提升
(二)在变量和函数都有的情况下函数的声明比变量的声明会
优先
(三)变量在函数内的提升也需要考虑函数参数的影响。
变形一下可以这样看
这里是通过
var
声明的变量通过它声明的变量只提升声明不提升赋值 声明和赋值是两回事。如果根据 执行上下文的内容来解释就是 在执行上下文阶段 会经过一个创造的步骤 会创建变量对象 但在变量对象中会优先处理 、函数的参数、 其次 函数的声明、 最后 变量的声明 ,如果变量的声明和函数的参数或者是函数的声明发生冲突那么这个变量不会去干扰它们。
详细的解释函数的参数影响到变量声明的原因
(一)首先在执行上下文中有三个步骤分别是构建、执行、回收这个三个阶段 先看创建阶段如果感兴趣可以看到文末最后。
创建阶段
如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性
由于变量对象是存储上下文中所有定义的变量和函数声明,问题就出现在在了创建变量对象的身上。
引用一下mqyqingfeng对变量对象的总结
变量对象初始化的顺序:
(二)从另一个的角度来看 js 代码的执行过程分为三个阶段 1.生成抽象语法树 2.生成字节码 3.生成机器码
在第一个阶段又分为 词法分析和语法分析。词法分析阶段 JS会检测当前作用域中所有的变量和函数声明,然后将其添加到词法环境中
这里引用他对变量提升的理解-文章也写的非常不粗先看我的文章在看他的好嘛?
在词法分析阶段,对于变量声明和函数声明,词法环境的处理是不一样的:
var a = 3
,会为变量分配内存并初始化为undefined
,赋值语句在生成机器码阶段真正执行代码的时候才进行。function sayHello() { console.log('Hello there!') }
,会在内存里创建函数对象,并且直接初始化为该函数对象。因此,对于变量声明,在真正执行到赋值语句之前,我们就已经可以使用此变量,但是初值为
undefined
;而对于函数声明,在执行到函数声明之前,函数对象就已经存在在内存当中,并可以直接调用了。(三)在ES6中执行上下文又引入变量环境和词法环境的概念
执行上下文的生命周期:
重点看一下这两个词法环境和变量环境 由这两个共同组成了执行上下文。
词法环境有两部份组成:
变量环境其实也是一个词法环境, 因此它具有上面定义的词法环境的所有属性。
词法环境存储变量绑定(let 和 const)以及函数的声明。但变量环境仅仅用于存储 var 声明。
函数被直接存储到内存中,var 声明的变量名会被存储到变量环境中初始化为 undefiend 而通过let const 进行声明的会存储到词法环境中如果在赋值之前访问就会抛出错误。
推荐文章
关于具体的执行上下文还要具体的看我的下一个文章
深刻理解执行上下文
为什么会有变量提升和函数提升以及抽象泄露的概念虽然没什么用但很有意思
参考链接
我知道你懂 hoisting,可是你了解到多深?
JavsScript 变量提升和函数提升-涉及到了V8的字节码和js的工作流程可以抽空看看
JavaScript进阶-执行上下文
The text was updated successfully, but these errors were encountered: