由于非常感兴趣, 我查询了很多关于IIFE (immediately-invoked function expression)的东西, 如下:

(function (window, document, undefined) {// })(window, document);

那么为什么不写一篇关于它的文章呢? ;-)

首先,它有一系列不同的东西。从头开始:

作用域

JavaScript有function 作用域, 所以它被用在必须私有作用域的地方。举个例子:

(function (window, document, undefined) {var name = 'Todd';})(window, document);console.log(name); // name没有定义, 它在一个不同的作用域里面

Simple.

它的工作原理

一个普通的函数是这样的:

var logMyName = function (name) {console.log(name);};logMyName('Todd');

我们可以调用它的范围和我们提供的作用域没有关系。“IIFE”被创造的原因是它们是立即执行表达式,这意味着他们一创建就马上被执行,当然我们不能再次执行它们。 如下:

var logMyName = (function (name) {console.log(name); // Todd})('Todd');

这里的秘密武器是这个, (还记得上面分配了一个变量的例子吗?):

(function () {})();

如果没有额外的小括号,他们就不能工作:

function () {}();

虽然有一些技巧可以强制让javascript让它工作,如下使用! 字符:

!function () {}();

当然还有下面的变体:

+function () {}();-function () {}();~function () {}();

但是我不会使用他们.

查看 Disassembling JavaScript’s IIFE Syntax 这是一篇详细介绍IIFE语法和它的变体的文章。

参数

现在我们知道它是怎么工作了,我们可以往IIFE中传参:

(function (window) {})(window);

这个的工作原理是什么? 注意, 最后的 (window); 是函数的调用, 并且我们传入了一个window 对象。它通过这个传入到函数的变量,这个变量我们也命名为window 。 你可以认为这个是没有意义的,但是现在我们使用window 更好. 那么我们还能做什么? 我们可以传入更多的东西, 让我们传入一个document 对象:

(function (window, document) {// we refer to window and document normally})(window, document);

局部变量的调用比全局变量更快, 当然这是在超大规模的情况下,一般情况我们不会感觉到速度的影响 - 但是如果我们用全局变量很多也是值得考虑的。

什么是 undefined?

在ECMAScript 3, undefined是变量. 意味着它的值可以被定义,比如 undefined = true; 在 ECMAScript 5使用严格遵守模式('use strict';) 这个赋值会报错.:

(function (window, document, undefined) {})(window, document);

下面是可以得:

undefined = true;(function (window, document, undefined) {// undefined is a local undefined variable})(window, document);

压缩

压缩我们的变量是IIFE模式真正实用的地方。局部变量的名字可以在它们传入函数中进行改变,所以我们如下调用:

(function (window, document, undefined) {console.log(window); // Object window})(window, document);

变为:

(function (a, b, c) {console.log(a); // Object window})(window, document);

想象下,所有的你引入的类库里面的window 和 document 很好的压缩。 如下面的jquery类库的调用:

(function ($, window, document, undefined) {// use $ to refer to jQuery// $(document).addClass('test');})(jQuery, window, document);
(function (a, b, c, d) {// becomes// a(c).addClass('test');})(jQuery, window, document);

这意味着你不用使用 jQuery.noConflict(); 任何 $ 都会执行jquery. 学习这个对于变量的作用域会对你帮助很大。一个好的压缩工具会把undefined压缩为c。undefined 的命名是无关紧要的,我们只是需要用它来判断一个对象是否有值或者有没有定值而已

非浏览器全局环境

比如Node.js, 浏览器不在是全局对象,我们会使用IIFE让他在跨环境运行:

(function (root) {})(this);

在浏览器中,this 指向 window 对象, 所以我们不需要传入 window, 我们可以使用this来缩短. 我喜欢使用root来命名它,如果在非浏览器环境也合适

。 如果你对普通的解决方案感兴趣 这里是一个UMD包装:

(function (root, factory) {if (typeof define === 'function' && define.amd) {define(factory);} else if (typeof exports === 'object') {module.exports = factory;} else {root.MYMODULE = factory();}})(this, function () {// });

在浏览器, root.MYMODULE = factory(); 是我们的IIFE模块, 其他情况(如 Node.js) 它会调用 module.exports 或者当 typeof define === 'function' && define.amd为true 则调用requireJS。当然这个另外一个故事了, 我强烈推荐你看这篇文章 UMD repo.

(译)(function (window, document, undefined) {})(window, document); 真正的意思的更多相关文章

  1. JS (function (window, document, undefined) {})(window, document)的真正含义

    原文地址:What (function (window, document, undefined) {})(window, document); really means 按原文翻译 在这篇文章中,我 ...

  2. (function (window, document, undefined) {})(window, document)什么意思?

    1.IIFE(即时调用的函数表达式),它采取以下表达式: (function (window, document, undefined) { // })(window, document); Java ...

  3. javascript匿名函数自执行 (function(window,document,undefined){})(window,document);

    使用匿名自执行函数的作用: (function(window,document,undefined){})(window,document); 1.首先匿名函数 (function(){}) (); ...

  4. 详解jquery插件中(function ( $, window, document, undefined )的作用。

    1.(function(window,undefined){})(window); Q:(function(window,undefined){})(window);中为什么要将window和unde ...

  5. js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)

    一.浏览器同源策略 首先我们需要了解一下浏览器的同源策略,关于同源策略可以仔细看看知乎上的一个解释.传送门 总之:同协议,domain(或ip),同端口视为同一个域,一个域内的脚本仅仅具有本域内的权限 ...

  6. window.showModalDialog与window.open()使用

    window.showModalDialog 有些浏览器不兼容,尝试用window.open() 封装替代,需要打开子窗口后向父窗口传递数据. <html> <script src= ...

  7. 详解jquery插件中;(function ( $, window, document, undefined )的作用

    在jquery插件中我们经常看到以下这段代码 1 2 3 ;(function ( $, window, document, undefined ){ //函数体内具体代码 })(jQuery, wi ...

  8. jquery插件中(function ( $, window, document, undefined )的作用

    在jquery插件中我们经常看到以下这段代码 ;(function ( $, window, document, undefined ){ //函数体内具体代码 })(jQuery, window,d ...

  9. ;(function($,window,document,undefined){})(jQuery,window,document)

    ;(function($,window,document,undefined){})(jQuery,window,doucment) 1.自调函数(function(){})() 2.好处是不会产生任 ...

随机推荐

  1. vue+elementUI+axios实现的全局loading加载动画

    在项目中,很多时候都需要loading加载动画来缓解用户的焦虑等待,比如说,我打开了一个页面,而这个页面有很多接口请求,但浏览器的请求并发数就那么几个,再加上如果网速不行的话,那么这时候,用户很可能就 ...

  2. redis connection refused: connect 启动失败

    先到redis解压包下执行 ./redis-server redis.conf 再连接 redis-cli

  3. BeanUtils 日期转换(本地格式yyyy-MM-dd)转换成date

    1.BeanUtils工具的使用 1)beanUtils 可以便于对javaBean的属性进行赋值. 2)beanUtils 可以便于对javaBean的对象进行赋值. 3)beanUtils可以将一 ...

  4. Docker配置镜像加速

    1.获取镜像地址 1.1.阿里云 打开网址:https://cr.console.aliyun.com/#/accelerator        注册.登录.设置密码        然后在页面上可以看 ...

  5. OSPFv3实验配置(GNS3)

    实验目的 1. 掌握 OSPFv3(v2) 的配置方法 2. 掌握在帧中继环境下 OSPFv3 (v2)的配置方法 3. 掌握 OSPFv3(v2) NSSA 的配置方法 4. 掌握外部路由汇总的配置 ...

  6. 安卓ADB学习笔记

    ADB(Android Debug Bridge)可以远程调试安卓设备,包括模拟器,可以进入终端模式(安卓本身相当于一个linux) 1.配置adb环境变量 以夜神模拟器为例,将模拟器安装路径里的bi ...

  7. BeautifulSoup爬网页图片

    #-*- coding: utf-8 -*- import urllib2 import urllib import os from BeautifulSoup import BeautifulSou ...

  8. 我常用的sublime快捷键整理

    由于很多人用sublime作为编辑器,我想我平时学习的时候也可以用sublime写demo,顺便熟悉一下sublime的使用方法.慢慢发现sublime中快捷键能节省很多时间,很方便,但是同时快捷键很 ...

  9. Lambda表达式概念与基本语法

    Lambda表达式是Java 8的重要更新,一个被广大开发者期待已久的新特性.Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被 ...

  10. Centos7.2正常启动关闭CDH5.16.1

    1.正常的启动.关闭流程     关闭流程 cluster1 stop Cloudera Management Service stop 4台agent:systemctl stop cloudera ...