本笔记为学习网易云课堂上的【撩课-零基础玩转JavaScript】所做。
目录
1. 概念
2. 预解析过程
3. 变量提升
4. 例子
JS代码的执行是由浏览器的JS解析器来执行的,JS解析器执行JS代码的时候,分为两个过程:预解析过程和代码执行过程。
1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
2. 把函数的声明提升到当前作用域的最前面,生成函数定义,只会提升声明,不会提升调用
3. 先提升变量,再提升函数
注意:函数声明提升,函数表达式不提升。
变量提升:定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升
函数提升:JS 解析器会把当前作用域的函数声明提前到整个作用域的最前面
例 1
console.log("hello world"); var num1 = 100; var num2 = 200; var str = '张三'; function sum(){} sum() function log(){} log();
JS解析器执行以上JS代码顺序说明如下。
预解析过程:
先把变量的声明提升到当前作用域的最前面,此时只会提升声明不会提升赋值,执行:
var num1,num2, str;
把函数的声明提升到当前作用域的最前面,生成函数定义,此时只会提升声明,不会提升调用,执行:
function sum(){}
function log(){}
代码执行过程:
自上而下执行,为变量赋值。执行 :
console.log("hello world");
num1 = 100;
num2= 200;
str = '张三';
sum();
log();
完成
例 2
console.log(num1); var num1 = 100; //undefined
说明:因为打印 num1 的时候 num1 已声明但未赋值,所以打印 num1 时值为 undefined。
JS解析器执行以上JS代码顺序说明如下。
预解析过程:
先把变量的声明提升到当前作用域的最前面,此时只会提升声明不会提升赋值,执行:
var num1;
代码执行过程:
自上而下执行,为变量赋值。执行 :
console.log(num1);
num1 = 100;
完成
例 3
console.log(fn2); //[Function: fn2] function fn2(){ console.log('我是函数'); } var fn2 = '我是变量'; console.log(fn2); //我是变量
JS解析器执行以上JS代码顺序说明如下。
预解析过程:
先把变量的声明提升到当前作用域的最前面,此时只会提升声明不会提升赋值,执行:
var fn2;
把函数的声明提升到当前作用域的最前面,生成函数定义,此时只会提升声明,不会提升调用,执行:
function fn2(){}
代码执行过程:
自上而下执行,为变量赋值。执行 :
console.log(fn2); //因为此时已声明变量跟函数,因为函数是后于变量声明的,所以输出: [Function: fn2]
fn2 = '我是变量';
console.log(fn2); //因为此时对变量赋值了,所以变量 fn2 覆盖了函数 fn2,所以输出:我是变量
完成
例 4
var str1 = '撩课'; fn1(); function fn1(){ console.log(str1); //undefined var str1 = 'itlike'; }
说明:调用函数 fn1时,打印 str1,在当前作用域中查找 str1,搜索到当前作用域中有 str1,不再搜索上一级作用域链。
函数 fn1 作用域JS代码顺序说明如下。
预解析过程:
先把变量的声明提升到当前作用域的最前面,此时只会提升声明不会提升赋值,执行:
var str1;
代码执行过程:
自上而下执行,为变量赋值。执行 :
console.log(str1); //因为此时已完成变量 str1 声明,未完成变量 str1 赋值,所以输出 undefined
str1 = 'itlike';
完成
例 5
说明:var num1 = num2 = num3 = 100; 局部声明 num1,全局声明 num2、num3。所以在全局打印 num1 时,会报错。