变量提升与函数提升

  • Post author:
  • Post category:其他




一、解析顺序

步骤一:预解析阶段。该阶段的任务是先找出函数的声明将其提升到作用域最前面,然后再找出var操作符声明的变量并将其提升到作用域最前面但不赋值。

步骤二:执行阶段。赋值,运算,函数调用都在这个阶段。



一、变量提升

console.log(a);	//undefined
var a = 10;

其实际执行过程相当于

var a;
console.log(a);	
a = 10;


注:变量的提升其实就是将用var声明的变量,提升到作用域的顶端,然后在同样的作用域中书写变量赋值的地方给变量赋值



二、函数提升

  1. 两种创建函数的方式

    //function definition 函数定义
    function func(){
    	
    }
    //function expression 函数表达式
    var a = func(){}
    
  2. 函数定义声明的函数可以提升声明,对于函数表达式,只有在执行到相应的语句时才进行解析。函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用。

    (1)函数定义声明函数

    func();		
    function func(){
    	console.log("hello");	
    }
    

    其解析结果相当于

    function func(){
    	console.log("hello");
    }
    func();
    

    (2)函数表达式声明函数

    console.log(a)		//undefined
    a();				//a is not a function
    var a = function func(){
    	console.log("hello");
    }
    

    其解析结果相当于

    var a;
    console.log(a);	//undefined
    a();		//a is not a function
    a = function(){
    	console.log("hello");
    }
    a();	//hello
    
  1. 函数名指向内存地址,内存地址指向函数本身
  2. js解析器优先解析函数声明,然后解析使用var操作符声明的变量,但不赋值。遇到赋值操作符的时候才会赋值。
  3. 赋值操作是执行代码时的步骤。
  1. 一个demo没有想明白

    func();		//undefined;	10;
    {
    	func();	//嘿嘿
    	function func(){
    		console.log("嘿嘿");
    	}
    	func(); //嘿嘿
    }
    func();		//嘿嘿
    
    function func(){
    	console.log(a);
    	var a = 10;
    	console.log(a);		
    }
    func();		//嘿嘿
    



三、一些补充

  1. 解析与执行顺序

    var a = 10;
        x();
        function x(){
            var b = 20;
            alert( b );
        }
        alert( a );
        /*
        执行顺序:
        执行全局作用域:
            1、定义
                var a ;
                function x(){
                    var b= 20;
                    alert( b );
                }
            2、执行步骤
                a = 10;
                x(); ====>新的作用域触发====>依照上面的规则:1、定义
                                                                var b;
                                                             2、执行步骤
                                                                b = 20;
                                                                alert( b ); 弹出 20;
               回来父级这层开始向下执行
               alert( a ); 弹出10;
    
  2. 同局作用域 变量与函数重名。

        var a;
        function a(){
            alert(1);
        }
        a();
    先执行定义步骤 var a    function a(){alert(1);}
    var a会被函数覆盖===>保留function a(){alert(1);}
    再来执行步骤
    a()  ==>弹出1function a(){
    		alert(1);
    	}
    	var a;
    	consol.log(a);			//[Function: a]
    
        var a = 10;
        function a(){
            alert(1);
        }
        a();
    
    先执行定义步骤 var a    function a(){alert(1);}
    var a会被函数覆盖===>保留function a(){alert(1);}
    再来执行执行步骤
    a = 10
    a()  ==>报错  现在a是10
  3. 函数带有形参且调用时传了实参

    function say(a, b){
    	//函数执行时相当于var a = 10,b;
    	console.log(a,b);
    }
    say(10);
    

2021/3/13

推荐大家看这篇博客,可以更加从源头理解为什么


深入理解 JavaScript 执行上下文和执行栈



版权声明:本文为qq_41884544原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。