变量提升处理机制

变量提升处理机制

变量提升:在当前上下文中(全局/私有/块级),JS代码自上而下执行之前,浏览器会处理一些事情(可以理解为词法解析的一个环节,词法解析一定是发生在代码执行之前的):会把当前上下文中所有带var/function关键字的进行提前声明或者定义

var a = 10;
① 声明 declare:var a;
② 定义 defined:a = 10;

带VAR的只提前声明
带FUNCTION的会提前声明+定义:函数名就是变量名,函数是对象数据类型的需要堆内存存储

(1)var的变量提升

 console.log(a); //=> undefined
 var a = 12; //=> 创建12,a=12 赋值(声明在变量提升阶段完成了,浏览器懒得不会做重复的事情)
 a = 11; //=> 全局变量 a = 11;
 console.log(a); //=> 11

△ var变量提升

数据类型
① 基本数据类型(string/number/boolean/null/undefined/symbol/bigint)
② 对象数据类型(object/function)
① 基本数据类型值:直接存储在栈内存中
② 对象数据类型值:由于数据类型比较复杂,存储在堆内存中,把堆内存的16进制地址放到栈内存中与变量关联起来

(2)function的变量提升

 fn(); //=> 函数执行的结果:输出"hello"  (在变量提升阶段已经申明和定义了)
 function fn(){
     var a = 12;
     console.log('hello');
 }

△ function变量提升

函数表达式

 fn(); //=> Uncaught TypeError: fn is not a function
 // 报错 后面的代码就不执行了
 var fn = function (){
     // 函数表达式:在变量提升阶段只会声明fn,不会赋值了
     console.log('hello');
 };
 fn();

△ 函数表达式

匿名函数具名化

var fn = function AA(){
     console.log('hello');
 };
 AA(); //=> Uncaught ReferenceError: AA is not defined
var fn = function AA(){
    console.log('hello');
    console.log(AA); //=> 输出当前函数体
};
fn();

△ 匿名函数具名化

把原本作为值的函数表达式的匿名函数“具名化”:
① 这个名字不能在函数体外部访问,也就是不会出现在当前上下文中
② 函数执行时,形成私有上下文,会把这个“具名化”的名字作为该上下文中的私有变量(它的值就是这个函数体)来处理
③ 在函数体内部不能修改这个名字的值,除非是重新声明这个变量

(3)不带var的
 console.log('ok'); //=> 'ok'
 //=> 没有写var/function的,不能在定义前使用
 console.log(a); //=> Uncaught ReferenceError: a is not defined
 a=12;
 console.log(a);

△ 不带var的

(4)带let的

 console.log('ok'); //=> 'ok'
 //=>let/const 没有变量提升
 console.log(a); //=> 报错 Uncaught ReferenceError: a is not defined
 let a = 12;
 a = 13;
 console.log(a);

△ 带LET的

(5)在全局上下文的映射

基于var/function在全局上下文中声明的变量(全局变量)会“映射”到window全局对象上一份,作为它的属性;而且一个修改另外一个也会跟着修改

 var a = 12;
 console.log(a); //=> 12 全局变量
 console.log(window.a); //=> 12 映射到GO上的属性
 window.a = 11;
 console.log(a); //=> 11 映射机制:一个修改另一个也会修改

△ 全局上下文的映射机制

(6)例题:

 fn();//====> 5
 function fn(){ console.log(1); } //=>不再处理,变量提升阶段搞过了
 fn();//====> 5
 function fn(){ console.log(2); } //=>不再处理,变量提升阶段搞过了
 fn();//====> 5
 var fn = function(){ console.log(3); } //=>var fn不用在处理了,但是赋值在变量提升阶段没处理过,此处需要处理赋值fn=window.fn=>3
 fn();//====> 3
 function fn(){ console.log(4); }
 fn();//====> 3
 function fn(){ console.log(5); }
 fn();//====> 3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值