zoukankan      html  css  js  c++  java
  • 函数声明与函数表达式、变量提升

    函数的声明方式

    在定义一个函数的时候通常有两种声明方式:

    foo(){};     // 函数声明
    var foo = function(){};    // 函数表达式

    不同之处

    1. 函数表达式后面加括号可以直接执行
    2. 函数声明会提前预解析

    预解析

    让我们先看一个例子:

    foo();         //  函数声明
    foo_later();     //  foo_later is not a function
    
    function foo(){ console.log('函数声明'); }
    var foo_later = function(){ console.log('函数表达式'); }

    可以看到,函数声明foo被预解析了,它可以在其自身代码之前执行;而函数表达式foo_later则不能。要解决这个问题,我们先要弄清楚JavaScript解析器的工作机制。

    变量提升(hoist)

    JavaScript解析器会在自身作用域内将变量和函数声明提前(hoist),也就是说,上面的例子其实被解析器理解解析成了以下形式:

    function foo(){ console.log('函数声明'); }    // 函数声明全部被提前
    var foo_later;     // 函数表达式(变量声明)仅将变量提前,赋值操作没有被提前
    
    foo();             
    foo_later();     
    
    
    foo_later = function(){ console.log('函数表达式'); }

    这样也就可以解释,为什么在函数表达式之前调用函数,会返回错误了,因为它还没有被赋值,只是一个未定义变量,当然无法被执行。

    同样的,我们也可以试着猜测下面这段代码的输出结果:

    console.log(declaredLater);   
    
    var declaredLater = "Now it's defined!";
    
    console.log(declaredLater);    

    该段代码可以被解析成一下形式:

    var declaredLater;          
    
    console.log(declaredLater);    // undefined
    
    declaredLater = "Now it's defined!";
    
    console.log(declaredLater);    // Now it's defined!

    变量声明被提到最前(所以不会报出变量不存在的错误),但赋值没有被提前,所以第一次的输出结果是undefined。

    需要注意的是

    由于函数声明会被预解析,所以不要使用此种方法来声明不同函数。尝试猜想下面例子的输出结果:

    if(true){
      function aaa(){
        alert('1');
      }  
    }
    else{
      function aaa(){
        alert('2');
      }
    }
    
    aaa();

    与我们预想的不同,该段代码弹出的是“2”.这是因为两个函数声明在if语句被执行之前就被预解析了,所以if语句根本没有用,调用aaa()的时候直接执行了下面的函数。

    总结

    通过上面的讲解可以总结如下:

    • 变量的声明被提前到作用域顶部,赋值保留在原地
    • 函数声明整个“被提前”
    • 函数作为值赋给变量时只有变量“被提前”了,函数没有“被提前”

    通过练习上面的实例自己多感受一下。另外,作为最佳实践:变量声明一定要放在作用域/函数的最上方(JavaScript 只有函数作用域!)。

     

    参考:

    JavaScript 中对变量和函数声明的“提前(hoist)”

    函数声明 VS 函数表达式

  • 相关阅读:
    词法分析程序
    关于编译原理
    超神c语言文法
    linux基本命令
    用bat来注册ocx
    当web配置文件 appSettings配置的东西越来越多时,可以拆开了。
    MVC的URL路由规则
    ASP.NET MVC 中如何实现基于角色的权限控制
    查cc攻击
    关于session介绍
  • 原文地址:https://www.cnblogs.com/timl525/p/5092132.html
Copyright © 2011-2022 走看看