执行上下文和执行上下文栈

1.变量提升:

通过var定义(声明)的变量,在定义之后就可以访问到值,undefined

2.函数提升

通过function声明的函数,在之前就可以直接调用

面试题:

 var a = 3;
 function fn () {
    console.log(a);
    var a = 4;
   }
    fn() //undefined

当调用fn这个函数的时候,执行打印变量a,首先会在fn的作用域中寻找,由于在下面是var变量

会在函数中首先定义,不过值是undefined

console.log(b); // 在前面可以访问到,不过值是undefined
        fn2();//可以调用
        fn3();//不能调用 这个地方是变量提升
        var b = 3;
        function fn2() {
            console.log('fn2')
        }
        var fn3 = function () {
            console.log('fn3');
        }

在var b是相当于在window的全局作用域声明了b,不过值是undefined。并且fn2函数也已经执行(不是调用)

执行上下文和执行上下文栈_第1张图片

 用function定义的函数已经预处理执行了,但是fn3的函数还未执行,未函数提升

3.全局执行上下文

在执行全局代码将window确定为全局执行上下文

对全局数据进行预处理

        var定义的全局变量 定义为undefined

        function声明的全局变量 添加为window的方法

        this赋值为window

 console.log(a1);   //undefined
    a2()               //a2
    console.log(this); //window
    var a1 = 3
    function a2(){
        console.log('a2()');
    }

4.函数执行上下文

在调用函数准备函数之前,创建对应函数执行上下文

对局部数据进行预处理

形参变量  赋值  添加上下文执行属性

arguments 赋值  添加上下文执行属性

var定义的局部变量 undefined

fucntion声明的函数  赋值 添加上下文方法

this赋值调用函数的对象

        function fn (a1) {
        console.log(a1); //2
        console.log(a2); //undefined
        a3();//a3()
        a4()//a4 is not a function
        console.log(this);//windiw
        console.log(arguments);//2,3 类数组 伪数组

        var a2 = 3
        function a3() {
            console.log('a3()');
        }

        var a4=function(){
            console.log('a4()')
        }
    }
    fn(2,3)

因为赋值给a1=2; 因为a3是function声明的函数,函数提升所以可以调用;因为a4是定义函数没有函数提升,只有变量提升;因为fn是window调用,所以this是window;arguments是2,3伪数组

5.执行上下文栈

1.在全局代码执行前,js引擎就会创建一个栈来管理存储所有的执行上下文对象

2.在全局执行上下文window确定后,将其添加到栈中(压栈)

3.在函数执行上下文创建后,将其添加到栈中(压栈)

4.在函数执行完之后,将栈顶的对象移除(出栈)

5.在当前函数执行完之后,栈中只剩window

因为执行函数的时候才会产生上下文,window,bar,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)
    }

面试题:

1.

    console.log('global begin'+i);
    var i =1;
    foo(1);
    function foo(i){
        if(i==4){
            return;
        }
        // 这里是结束的条件
        console.log('foo()begin'+i);
        foo(i+1);// 函数内部调用自己
        console.log('foo() end'+i);
    }
    console.log('global end'+i);

//global beginundefined
//foo()begin1
//foo()begin2
//foo()begin3
//foo() end3
//foo() end2
//foo() end1
//global end1

因为是栈结构,所以后进先出

 2.

    function a(){}
    var a;
    console.log(typeof a);

先变量提升并赋值 undefined,然后函数提升并覆盖掉变量提升赋值的undefined,所以为 'function'

3.

 if(!b in window) {
        var b = 1;
    }
    console.log(b); //undefined

因为b经过变量提升在window对象中,所以b in window是true,所以不能进去if判断,所以不能直接执行,所以b是undefined

4.

  var c =1;
    function c(c){
        console.log(c)
    }
    c(2);

首先进行变量提升undefined,后再进行函数提升,再赋值c=1,然后得到最终结果是c is not a function

你可能感兴趣的:(js,javascript)