学习深入理解JavaScript系列(4)-立即调用函数表达式
立即调用函数表达式
任何function
在执行的时候都会创建执行上下文。相当于自己的私有变量:
function makeCounter () { var i = 0; return function () { console.log(i++); } } var counter1 = makeCounter(); counter1(); //log : 1; counter1(); //log:2 var counter2 = makeCounter(); counter2(); //log:1 counter2(); //log:2
counter1与counter2是两个不同的实例 (应该是单例模式)
以下每个也为实例,静态方法与原型链方法区别
var aa = function () { this.i = 0; this.k = 0; this.count = function () { console.log(this.k++) } } aa.prototype = { log : function () { console.log(this.i++) } } var a1 = new aa(); a1.count() // log 0 a1.count() //log 1 a1.log(); // log 0 a1.log();// log 1 var a2 = new aa1; a2.count() // log 0 a2.count()// log 1 a2.log(); // log 0 a2.log();// log 1
一般函数表达式需要在哎后面加一个()
即可实现自执行。
var foo = function () {}();
但是下面函数声明中由于括号只是一个分组操作符,没有包含函数表达式。
function foo(){}()
但是如果括号包含有表达式,虽然不报错,但是:
function foo () {}(1)
等价于
function foo () {}; (1)
但是当括号包括整个语句即可。可以把函数声明变为表达式
(function (){}()) //推荐 (function () {})()
自执行还可以:
new function (){} //必须是小写function,不能为Function。此时返回object new function (data){console.log(data)}(3) //传参
闭包保存状态
由于闭包传参的时候,可以lock参数
var eles = document.getElementsByTagName('a'); for (var i = 0; i < eles.length; i++) { eles[i].addEventListener('click', function () { e.preventDefault(); console.log('i is ' + i); }, 'false') }
由于变量i没有进行lock,所以循环以后,点击的时候i才获得值,也就是最后一个。此时需要闭包进行lock。虽然循环完毕,i的值进行变化,但是由于闭包自执行使得i的值lock.
var eles = document.getElementsByTagName('a'); for (var i = 0; i < eles.length; i++) { (function (k) { eles[k].addEventListener('click', function () { e.preventDefault(); console.log('i is ' + k); }, 'false') })(i) }
或者
var eles = document.getElementsByTagName('a'); for (var i = 0; i < eles.length; i++) { eles[k].addEventListener('click', (function (k) { return function () { e.preventDefault(); console.log('i is ' + k); } })(i), 'false') }
自执行匿名函数与匿立即执行的函数表达式
function foo() { foo() } //自己执行自己,自执行函数 但 var foo = function () { foo() } //可能是自执行匿名函数 仅仅是 foo 引用自身 var foo = function () { arguments.callee()} //自己调用自己 但是没有标记名称 是自执行匿名函数 ( function () {} ()) //立即执行 (function foo () {foo()} ()) // 立即调用自身的函数也可以自执行 (function () { arguments.callee ()}() ) // 立即调用自身的函数也可以自执行
自执行一个应用:Module 模式:
var counter = (function () { var i = 0; rerurn { get : function () { return i; } } }())
Written on April 27, 2015