JS函数之---立即执行函数(IIFE)

JavaScript08

JS函数之---立即执行函数(IIFE),第1张

Immediately-Invoked Function Expression(IIFE立即执行函数表达式)

可以让函数在创建后立即执行 必须是一个表达式

1、函数的定义方式一: 函数声明

2、函数的定义方式二: 函数表达式(匿名函数表达式、命名函数表达式)

1、错误写法 直接报错 js引擎看到function关键字会认定后面跟的是函数定义语句,此时后面如果直接加上()会被当做分组操作符,而分组操作符必须有表达式,所以此时报错

2、立即执行函数的正确写法,让js引擎认为这是一个表达式

1、立即执行函数不能再外面再被调用,执行完之后已经被立即销毁了。所以立即执行函数的函数名称可以省略, 统一使用匿名函数表达式

2、由于立即执行函数,执行完后就立即被销毁了 所以它可以创建一个独立的作用域,而且该作用域里面的变量,外面访问不到。因此就可以避免变量污染

正确输出写法:用立即执行函数将i作为参数传入,立即函数每次执行时,会把参数i的值复制一份。然后再创建函数作用域来执行函数

1、立即执行函数和闭包只是有一个共同有点就是都能减少全局变量的使用

2、立即执行函数只是函数的一种调用方式,声明完后立即调用,一般只能调用一次,调用完后会立即被销毁,不会占用内存,有自己的独立作用域,外部不能调用

3、闭包则主要是让外部函数可以访问内部函数的作用域,也减少了全局变量的使用,保证了内部变量的安全,但是被引用的内部变量不会被销毁,增大了内存消耗,使用不当会容易造成内存泄露

可参考: https://www.cnblogs.com/wenxuehai/p/10357274.html

即执行函数(Immediate Functions)立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行,比如:[javascript] view plain copy(function () { alert('watch out!') }()) 这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行;立即执行函数(immediate function)术语不是在ECMAScript标准中定义的,但它很短有助于描述和讨论模式;这种模式有一些几部分组成:使用函数表达式定义一个函数(函数声明不能起作用)在结尾加上一对括号,让函数立即被执行将整个函数包裹在一对括号中(只有在你不将函数赋值给一个变量的时候才需要)下面这种可选的语法形式也是很常见的(注意结尾的一对括号),但JSLint趋向于第一种:[javascript] view plain copy(function () { alert('watch out!') })() 这种模式是非常有用的,因为它为你初始化代码提供了一个作用域的沙箱;考虑一下下面这种常见的场景:你的代码在页面代码加载完成之后,不得不执行一些设置工作,比如附加时间处理器,创建对象等等,所有的这些工作只需要执行一次,所以没有理由创建一个可复用的命名的函数,但这些代码也需要一些临时的变量,但初始化过程结束后,就再也不会被用到了,所以将这些变量作为全局变量不是个好主意,所以我们需要立即执行函数——去将我们所有的代码包裹在它的局部作用域中,不会让任何变量泄露成全局变量;[javascript] view plain copy(function() { var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], today = new Date(), msg = 'Today is ' + days[today.getDay()] + ', ' + today.getDate() alert(msg) } ())// "Today is Fri, 13" 如果代码没有被包裹在立即执行函数中,那么局部变量days,today和msg都将成为全局变量,初始化代码的遗留产物。立即执行函数的参数(Parameters of an Immediate Function)你也可以给立即执行函数传递参数,就像下面的例子一样:[javascript] view plain copy// prints: // I met Joe Black on Fri Aug 13 2010 23:26:59 GMT-0800 (PST) (function(who, when) { console.log("I met " + who + " on " + when) } ("Joe Black", new Date())) 通常,全局变量被作为一个参数传递给立即执行参数,这样它在函数内部不使用window也可以被访问到:这种方式可以让代码在环境(除了浏览器)中更加通用:[javascript] view plain copy(function (global) { // access the global object via `global` }(this)) 记住:通常你不应该给立即执行函数传递太多的函数,因为它很快会成为一个负担——为了理解代码是如何工作的,你不得不经常上下滚动源代码。立即执行函数的返回值(Returned Values from Immediate Functions)就像其它任何函数一样,一个立即执行函数也能返回值并且可以复制给其它变量:[javascript] view plain copyvar result = (function () { return 2 + 2 }()) 另外一种实现相同的功能的方法是省略包裹函数的括号,因为当你将立即执行函数的返回值赋值给一个变量时它们不是必需的;[javascript] view plain copyvar result = function () { return 2 + 2 }() 这种语法是非常简单的,但它可能看起来有点令人误导;如果没有注意到函数结束的括号,一些人可能就会认为result指向一个函数;实际上result指向立即执行函数的返回值,在这种情况下是数字 4 。还有另一种语法可以实现相同的功能:[javascript] view plain copyvar result = (function () { return 2 + 2 })() 在前面的例子中返回一个基本类型的整数作为立即执行函数的返回值;但是除了基本类型值,立即执行函数也能返回任何类型的值,包括其它的函数;那么,你可以利用立即执行函数的作用域为返回的内部函数私下里存储一些数据。在接下来的例子中,立即执行函数的返回值是一个函数——被赋值给了变量getResult,这个函数简单的返回了res的值,这个值事先被计算并被储存在立即执行函数的闭包中:[javascript] view plain copyvar getResult = (function() { var res = 2 + 2 return function() { return res } } ()) 立即执行函数也可以用来定义对象的属性;假如,你需要定义一个很可能在对象生命周期中都不会改变的属性,但在你定义之前,你需要做一下工作去计算出正确的值;你可以使用立即执行函数去封装这些工作,并且立即执行函数的返回值将会成为属性的值,下面的代码:[javascript] view plain copyvar o = { message: (function() { var who = "me", what = "call" return what + " " + who } ()), getMsg: function() { return this.message } } // usage o.getMsg()// "call me" o.message// "call me" 在这个例子中,o.message是一个字符串类型的属性,不是一个函数,但它需要一个函数在脚本被载入时被执行并帮忙定义属性。好处和用法(Benefits and Usage)立即执行函数模式被广泛使用,它可以帮你封装大量的工作而不会在背后遗留任何全局变量。你定义的所有变量都会成员立即执行函数的局部变量,所以你不用担心这些临时变量会污染全局空间。这种模式经常被使用在书签工具(bookmarklets)中,因为书签工具在任何页面上运行并且保持全局命名空间干净是非常必要的;这种模式也可以让你将独立的功能封装在自包含模块中(self-contained modules)。假如你的页面是稳定的并且在没有JavaScript情况下能正常工作,然后本着逐步加强的想法,你加入了一些代码加强页面某个方面;你可以将这些代码封装进一个立即执行函数中,并且确保页面没有它的情况下也能正常工作。然后你可以添加更多的加强模块,移除它们,单独测试它们,允许用户去禁用它们等等。你可以使用下面的模板去定义一个函数模块,让我们叫它module1:[javascript] view plain copy// module1 defined in module1.js (function () { // all the module 1 code ... }())

js中是有立即执行函数的,比如说js文件中有一个函数为:

function sayHello(){

console.log('Hello World!')

}

如果你想在js文件加载后,立即执行sayHello()函数,那么可以在js中加入

sayHello()的调用即可。