JS之预解析

对于javascript之父Brendan Eich而言

“它的优秀之处并非原创,它的原创之处并不优秀。”

主要内容如下:

  1. javascript的预解析。

  2. javascript的全局作用域和局部作用域(函数)。

  3. javascript的声明函数、函数表达式以及匿名函数。

javascript的预解析

  1. 变量、函数表达式提升

    问: console.log 语句的输出结果为什么?

     if (i > 0) {  
            var i = 1;  
    }  
    console.log(i);     
    
  • 答案:undefined。

  • 解析:因为js只有函数级作用域,所以js中的局部变量的声明和函数表达式都会被“提升”至当前作用域的顶端,并且只提取变量,不提取值,函数则可在其上方带哦用。没有赋值的初始变量和函数的默认返回值均为undefined。这段代码相当于:

     var i;  
    if (i > 0) {  
            i = 1;  
    }  
    console.log(i);
    

javascript的作用域

Javascript的作用域只有两种:全局作用域和局部作用域。

局部作用域是用函数的花括号来表示的,if、for语句中的花括号不是独立的作用域。

全局变量可以在任何地方访问。注意:所有末定义直接赋值的变量自动声明为全局变量。

函数内部的变量,对外部是不可见的。

函数内部可以访问外部函数的变量,内部没有值可以由内到外的搜索。

javascript的声明函数、函数表达式以及匿名函数

  1. 声明函数:使用关键字function+函数名来声明的函数。

    function fn(){
        console.log("hahah");
    }
    fn();
    
  2. 函数表达式:使用function关键字,但没有函数名,且赋值给一个变量的函数。

    var fn = funxtion(){
        condolr.log("hahah");
    }
    fn();
    
  3. 匿名函数:使用function关键字,但是没有函数名。优点:函数封装,保护变量,不会代码污染。

    funxtion(){
        console.log("hahah");
    }();
    

    注意:当匿名函数前面有运算符时,会解析成函数表达式。

    !funxtion(){
        console.log("hahah");
    }();
    
  4. 自执行匿名函数:

    常见格式:

    (function() { /* code */ })();
    

    解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。

    作用:可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式。

    其他写法

    (function () { /* code */ } ()); 
    !function () { /* code */ } ();
    ~function () { /* code */ } ();
    -function () { /* code */ } ();
    +function () { /* code */ } ();
    

    推荐阅读:立即调用的函数表达式


课后思考:建立一个函数可以模拟加减乘除。