Skip to content

一、变量提升和函数提升

1.变量提升

  • 通过var声明的变量,在定义语句之前就可以访问,值为undefined。
  • 通过let声明的变量,在定义语句之前不能访问,会报错,初始化之前不能访问。

2.函数声明提升

  • 通过function声明函数,在声明之前可以直接调用。值:函数定义的对象
  • 箭头函数声明的函数,在之前访问,报函数未定义。
js
    var a = 3
    function fn(){
        console.log(a)//undefined
        var a = 4
    }
    fn();
    const c = 2;
    function fn1 (){
        console.log('c',c)//初始化之前不能访问c
        const c = 4;
    }
    fn1();

    console.log(b)//undefined 变量提升
    fn2()//函数提升
    var b = 4
    function fn2 (){
        console.log('f2')
    }
    fn3();//不能,变量提升
    var fn3 = function(){
        console.log('fn3')
    }
	fn4();//fn4未定义
        var fn4 = () => {
	    console.log('fn4')
	}

二、执行上下文

  1. 代码分类(位置)
    • 全局代码,函数代码(局部代码)
  2. 全局执行上下文
    • 执行全局代码前,将window确定为全局执行上下文对象
    • 对全局数据进行预处理,var定义的全局变量为undefined,添加为window属性,function声明的全局函数,添加为全局window方法 this赋值window
    • 开始执行全局代码
  3. 函数执行上下文
  4. 在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象
  5. 对局部数据进行处理
    • 形参变量=》赋值为(实参)=》添加为执行上下文属性
    • arguments=》赋值(实参列表),添加为执行上下文属性
    • var定义的局部变量=》undefined,添加为执行上下文属性
    • this=》赋值(调用函数的对象)
js
// 全局执行上下文
console.log(a1,window.a1)
a2();
console.log(this)
var a1 = 3
function a2(){
    console.log('a2')
}
console.log(a1)
// 函数执行上下文
function fn (a1){
    console.log(a1)//2
    console.log(a2)//undefined
    a3();//a3();
    console.log(this)//windows
    console.log(arguments)//2,3 //伪数组(2,3)
    var a2 = 3;
    function a3(a3){
        console.log('a3()')
    }
}
fn(2,3)

三、执行上下文栈

  1. 在全局代码执行前,js引擎就会创建一个栈来存储关联所有执行
  2. 在全局代码执行上下文(window)确定后,将其添加到栈中(压栈,在栈最下面)
  3. 在函数执行上下文创建后,将其添加到栈中(压栈)
  4. 在函数执行完成后,将栈顶的对象移除(出栈)
  5. 当所有代码执行完后,栈中只剩下window对象
    • 栈和队列:栈:后进先出,队列:先进后出
js
// 执行上下文栈:js执行函数,先有window,然后是执行的函数bar,然后是调用的函数foo。后面的foo先出栈
var a = 10;
var bar = function(x){
    var b = 5;
    foo(x+b)
}
var foo = function(y){
    var c= 5;
    console.log(a + c + y)
}
bar(10)
js
console.log(1,i) // undefined
var i = 1;
foo(i);
function foo(i){
    if(i == 4){
        return
    }
    console.log(2,i) // 1,2,3
    foo(i + 1) // 递归调用
    console.log(3,i) // 3,2,1
}
console.log(4,i) // 1

Released under the MIT License.