zoukankan      html  css  js  c++  java
  • javaScript函数提升及作用域

    代码片段:

    var a = 1;
    
    function foo() {
        console.log(a); //输出为undefined
        if (!a) {
            var a = 2;
        }
        alert(a);
    };
    
    foo();
    

    以上代码执行的结果为:2

    一、声明与定义

    1、声明:是指声称某样东西的存在,比如:一个变量或一个函数;

    var a; //声明变量
    

    2、定义:是指某样东西的具体实现,比如:一个变量的值是多少,一个函数的函数体是什么;

    var a = 1; //定义变量
    

    即:

    var a;     //声明变量
    a = 1;     //定义变量(赋值)
    var a = 1; //合二为一,声明变量并复制给它
    
    //当你认为你只做了一件事的时候(var a = 1;),
    //实际上解释器把这件事情分解成了两个步骤:一个是声明(var a;),另一个是定义(a = 1;)
    

    回到最开始的代码片段:

    var a = 1;
    
    function foo() {
        var a;      //变量提升至顶部
        if (!a) {
            a = 2;
        }
        alert(a);   //此时的a并不是函数体外的全局变量
    };
    
    foo();
    

    如代码所示,当进入函数体内时,又定义了新的变量a,当时其值为undefined,故if判断条件为真,接着为新的变量a赋值2,输出结果为2。

    二、作用域

    1、为什么不是在if语句内声明新变量a?
    答:因为javascript没有块级作用域,只有函数作用域,并不是代表遇见{ }就产生新的作用域。

    当解析器读到if语句时,发现其声明了新的变量a,解析器会将声明提升至作用域顶部(这是默认行为,并且无法改变),这一过程就是变量提升

    如果就是要输出结果为1,那就要在函数体内部创建新的作用域,如:

    var a =1;
    function foo(){
        if(!a){
    		(function(){  //会创建一个新的函数作用域,该作用域在函数体内部,故alert 
    			var a = 2;//不过根据“闭包”,这个作用域可以访问上层作用域
    		})();
        }
        alert(a);
    }
    
    foo();
    

    “请始终保持作用域内所有的变量声明都放置在作用域顶部。”

    2、在javascript中,有四种方式可以让命名进入到作用域中(按优先级排序):
    (1)语言定义的命名:如thisarguments,他们在所有作用域内都有效,并且优先级最高;
    (2)形式参数:函数定义时声明的形参会作为变量被提升至函数的作用域内,所以,形参是本地的,不是外部的或全局的,也可在执行函数时把外部变量传进来,传进来之后就变成本地的;
    (3)函数声明:函数体内部也还可以声明函数;
    (4)变量声明:即函数作用域内声明的变量会提升至作用域顶部。

    三、函数声明和函数表达式的差别

    1、当函数或变量提升时,只提升了声明,没有提升定义;
    2、比如:

    function test(){
    	foo();
    	function foo(){
    		alert("我是会出现的哦");
    	}
    }
    
    test();
    
    function test(){
    	foo();
    	var foo = function (){
    		alert("我是不会出现的哦");
    	}
    }
    
    test();
    

    具体来讲:
    栗子一:函数foo 是一个声明,既然是声明,就会被提升,这就是函数声明的提升,函数声明和函数体都将被提升至作用域顶部;
    栗子二:被提升的仅仅是函数名foo ,函数定义还停留在原处,因此在执行foo() 时,作用域只知道函数foo 的存在,不知道它是干嘛的,故执行会报错(undefined is not a function),这就是函数表达式,只有函数命名会提升,函数体还停留在原地。

    原文链接:https://segmentfault.com/a/1190000000348228

  • 相关阅读:
    sql语句 字段的赋值
    sql查询字段是否为空
    二分查找算法
    sql语句查看库里有没有这张表,有就删除
    字符串转换成元组
    python+selenium多窗口之间切换
    java代码实现highchart与数据库数据结合完整案例分析(二)---折线图
    java代码实现highchart与数据库数据结合完整案例分析(一)---饼状图
    java中集合格式及json格式的特点和转换
    substring()的用法和注意事项
  • 原文地址:https://www.cnblogs.com/gaos/p/7767469.html
Copyright © 2011-2022 走看看