资讯专栏INFORMATION COLUMN

深入理解JavaScript(一):变量提升

voidking / 2297人阅读

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

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

function fn() {
    console.log(a, b);//=>undefined 12
    var a = b = 13;
    console.log(a, b);//=>13 13
}

fn();
console.log(a, b);//=>12 13

undefined undefined:首先输出这个结果是因为变量提升,即前三行变成

var a;
var b;
console.log(a,b);//undefined undefined
a = 12;
b = 12;

undefined 12:接下来执行函数fn(fn一开始也被执行了变量提升,只不过函数中存储的都是字符串而已),对fn内部进行分析,即内部代码变成:

var a;
console.log(a,b);//undefined 12
a = 13;
b = 13; //不加var的本质是WIN的属性,即相当于window.b = 13; 
console.log(a,b);//13 13

一开始b在fn内部找不到,便会开始往上一层找,找到了全局的b,于是b输出12。
当经过var a = b = 13; 后,b被赋值为13,于是输出先从函数内部找b,找到了b=13,第二次输出b为13。(!同时,最先定义的全局变量b = 12也被赋值为13,故最后的b也等于13)

私有作用域中带var和不带var的区别:
1.带var的在私有作用于变量提升阶段,都声明为私有变量,和外界没有任何的关系
2.不带var不是私有变量,会向它的上级作用于查找,一直找到window为止(这种查找机制叫做:“作用域链”),也就是在私有作用域中操作的这个非私有变量,是一直操作别人的
只对等号左边进行变量提升
sum();
fn();// Uncaught TypeError: fn is not a function 

//=>匿名函数之函数表达式
var fn = function(){
    console.log("fn");
}//=>代码执行到此处会把函数值赋值给fn

//=>普通的函数
function sum(){
    console.log("sum");
}
条件判断下的变量提升
/*
 * 在当前作用域下,不管条件是否成立都要进行变量提升
 *   =>带VAR的还是只声明
 *   =>带FUNCTION的在老版本浏览器渲染机制下,声明和定义都处理,但是为了迎合ES6中的块级作用 
 *     域,新版浏览器对于函数(在条件判断中的函数),
 *     不管条件是否成立,都只是先声明,没有定义,类似于var
 */
console.log(a);//undefined
   if(1 === 2){
   var a = 3;
   }
   console.log(a);//undefined
重名问题的处理
fn();//=>4
function fn() {console.log(1);}
fn();//=>4
function fn() {console.log(2);}
fn();//=>4
var fn=100;//=>带VAR的在提升阶段只把声明处理了,赋值操作没有处理,所以在代码执行的时候需要完成赋值 FN=100
fn();//=>100() Uncaught TypeError: fn is not a function
function fn() {console.log(3);}
fn();
function fn() {console.log(4);}
fn();

带VAR和FUNCTION关键字声明相同的名字,这种也算是重名了(其实是一个FN,只是存储值的类型不一样)
关于重名的处理:如果名字重复了,不会重新的声明,但是会重新的定义(重新赋值)[不管是变量提升还是代码执行阶段皆是如此]

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

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

相关文章

  • 深入理解JavaScript执行上下文和执行栈

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

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

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

    leiyi 评论0 收藏0
  • 【进阶1-2期】JavaScript深入之执行上下文栈和变量对象

    摘要:本计划一共期,每期重点攻克一个面试重难点,如果你还不了解本进阶计划,点击查看前端进阶的破冰之旅本期推荐文章深入之执行上下文栈和深入之变量对象,由于微信不能访问外链,点击阅读原文就可以啦。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第一期,本周的主题是调用堆栈,今天是第二天。 本计划一共28期,每期...

    Richard_Gao 评论0 收藏0
  • 深入理解JavaScript执行上下文、函数堆栈、提升的概念

    摘要:原文链接变量对象是说的执行上下文中都有个对象用来存放执行上下文中可被访问但是不能被的函数标示符形参变量声明等。对于函数的形参没有什么可说的,主要看一下函数的声明以及变量的声明两个部分。 首先明确几个概念: EC:函数执行环境(或执行上下文),Execution Context ECS:执行环境栈,Execution Context Stack VO:变量对象,Variable Obj...

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

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

    tanglijun 评论0 收藏0

发表评论

0条评论

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