JS系列总结笔记——1. JavaScript的预解释机制(变量提升)

1. 概念

当浏览器加载HTML页面时,会先提供一个供全局JS代码执行的环境(即全局作用域,window或者global),在这个环境中,浏览器默认会把所有带varfunction的变量进行提前声明或者定义
(1) 理解声明和定义;

var num = 12;
// 声明: 告诉浏览器在全局作用域中有一个num变量
// 定义: 给变量进行赋值
// 使用只声明未定义的变量值为undefined;使用未声明未定义的变量直接报错

(2) 对于带varfunction关键字的变量在预解释时的操作不一样;
var关键字的提前声明,含function的提前声明并且定义。
(3) 此时的预解释只发生在当前的全局作用域下,函数内部的变量不发生预解释。执行函数时,函数内部的作用域同样会发生预解释。(关于函数执行时,内部发生的流程,见下一篇《JavaScript函数执行内部原理》


2.预解释机制的槽点

(1) 由于JavaScript没有块级作用域(es6有),在条件判断语句中的var也会被预解释,会带来如下问题。

if(!("num" in window)){ // "num" in window 此时变为true
    var num = 1;    // num 被预解释
}
console.log(num);  // 输出 undefined

(2) 匿名函数之函数表达式的预解释

fn(); // 报错
var fn = function() {
    console.log("hello world");
}
// 只对fn进行预解释,等号后面是一个匿名函数,不参与预解释。

(3) 自执行函数定义和执行一起完成,不进行预解释。
(4) return 下面的代码虽然不再执行,但是会预解释;return后面的都是返回值,不进行预解释。

function fn() {
    console.log(num);
    return function() {};
    var num = 1;
}
fn();  // 结果为undefined

(5) 在预解释时,如果名字已经声明过了,则不会再重新声明,但是会重新赋值。变量名和函数名一样也算冲突。

fn();  // 3
function fn() {console.log(1);}  // 预解释时声明+定义
fn();  // 3
var fn = 2; // 预解释时声明,执行时定义
fn();  // 报错
function fn() {console.log(3);}  // 预解释时定义

3. 实例
  • 例1:
console.log(str);   // undefined
var str = "test1";  // 预解释阶段声明全局变量str

console.log(str2);  // 报错
str2 = "test2";     // 不会参与预解释,只相当于给window添加了属性str2

console.log(fn1);   // 1
function fn1(){
    return 1;
}

关于全局变量和window属性的区别,点击这里

  • 例2:
 console.log(total);         // undefined
 var total = 0;
 function fn(num1,num2) {
     console.log(total);     // undefined
     var total = num1 + num2;
     console.log(total);     // 300
 }
 fn(100,200);
 console.log(total);         // 0

参考文章:
https://www.cnblogs.com/kawask/p/6225317.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值