lodash源码解读之模块化的基础——IIFE

2019-08-28 11:59:52 浏览数 (1)

IIFE(Immediately Invoked Function Expression),中文一般翻译为匿名立即执行函数

IIFE详解

构成

IIFE包含两部分。 第一部分是一个匿名函数,它包裹在分组操作符()中,拥有独立的词法作用域。 第二部分是再一次使用分组操作符(),创建一个立即执行函数表达式。Javascript引擎到此将立即执行函数。 大体结构如下所示:

代码语言:javascript复制
;(function(){
    // code
})();

优点

  • 匿名函数中的变量和方法,不能从外部访问
代码语言:javascript复制
(function () { 
    var name = 'wall';

    function sayHello(){
        console.log('hello');
    }
})();
// 外部不能访问变量 name 和方法 sayHello
name // undefined
sayHello() // sayHello is not defined

因为匿名函数有自己独立的词法作用域,所以会产生这种现象。

  • 匿名函数中可以正常访问更高词法作用域中的变量和方法
代码语言:javascript复制
// 浏览器环境下
var name = 'wall';

(function(){
    console.log(name); // 在控制台正常输出`wall`
})();

所以,IIFE并不是双向封闭的一个模块。模块内部可以有自己的私有方法和私有变量,也可以正常使用外部环境的变量和方法。

其他表现形式

代码语言:javascript复制
!function(){

}();

 function(){

}();

(function(){

}());

本质上,都是先将匿名函数转变为可执行的表达式,然后再用分组操作符执行。

IIFE在lodash中的应用

先上源码:

代码语言:javascript复制
;(function(){
    // code
}.call(this))();

第一个;的作用

工具库的源码,一般都是;开始。为什么要以这个符号作为开始,其实别有深意。

  • 第一个涉及到的是概念:语句

语句:是构成程序的基本单位,一条语句完成某种特定的操作。一般语句以分号;结束。

  • 另一个涉及到的是代码的优化手段:压缩合并 在前端的铁器时代,YaHoo出了一个著名的压缩代码工具——YUI Compressor。它的作用之一,就是将多个js文件源码,合并到一起,变成一个新文件。以此来减少页面加载时的HTTP请求数。 多个js文件压缩,总不免会出现黑天鹅,比如以下这种:
代码语言:javascript复制
// a.js
function say(){
    // code
}

// b.js
(function(){
    // code
})();

// a.js和b.js合并成c.js
// c.js
function say(){
    // code
}(function(){
    // code
})();

JavaScript引擎,解析c.js文件时,误将say方法进行执行,导致不可思议的事情发生。 而加上分号之后,则可以杜绝这种情况。

call的作用

call的使用,是为了显式指定当前匿名函数的上下文(context),由引用该工具库的环境所决定。

代码语言:javascript复制
function Foo(){
    (function(){
        console.log(this);  //Foo
    }).call(this);

    (function(){
        console.log(this); //undefined in strict or global
    })();
}

var test = new Foo;

参考

  1. MDN术语表-IIFE
  2. Why write “.call(this)” at the end of an javascript anonymous function?

关注我的项目(有帮助到你的话,麻烦点个star)

GitHub地址:lodash源码解读

0 人点赞