学习深入理解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
