Javascript 中的即时函数和初始化分支

本文介绍了JavaScript中的即时函数,包括其定义、使用场景及意义,并探讨了如何利用即时函数进行初始化任务,保持全局空间的洁净,同时展示了即时函数在创建对象属性、模块化初始化任务以及优化加载时分支的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

众所周知,在Javascript中,定义函数的方式有三种。
0. 定义函数的方式

//函数声明
function boo()
{
//函数体
}

//函数表达式
var boo = function()
{
//函数体
}

//命名函数表达式
var boo = function boo()
{
//函数体
};

1. Javascript中,还有一种函数的表现形式就是即时函数。顾名思义,即时函数就是可以在页面加载完该函数之后立即执行该函数的语法。
即时函数的写法:

//即时函数是一种支持在定义函数侯立即执行该函数的一种语法。
(function()
{
alert("immediate function");
}());

//也可以写成
(function()
{
alert("immediate function");
})();

2. 注意:即时函数是该函数加载完就会立即被执行,而不是等待页面加载完之后才执行即时函数,这和window.onload()和$(function(){})都是有区别的,所以即时函数是不能替代以上两者的,举个例子:

<html>
<head>
<title>即时函数</title>
<script language="javascript" type="text/javascript">
(function()
{
alert(document.getElementsByTagName("body")[0]);
//undefined,因为这个时候DOM元素<body>还没有被加载。
})();

//另一种方式
window.onload = function()
{
(function()
{
alert(document.getElementsByTagName("body")[0]);
//object, 因为window.onload是要等待页面的所以元素加载完
//才会执行的。
})();
};
</script>
</head>
<body>
</body>
</html>

3. 即时函数的意义,比如在页面加载时,必须执行一些任务,如附加事件处理程序,创建对象等任务,这些任务只需要执行一次,因此没有必要创建一个命名函数,而且这些初始化任务也需要一些变量,将这些变量定义到全局对象中是一个不完美的方法,因为这些变量也是只需要一次,应当尽量保持全局空间的洁净。那么这样的任务就可以用即时函数完成。
举例说明:

//即时函数能保持全局空间不受污染,能立即执行,可作为一些初始化工作,
//即时函数是非常有用的。
(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 Sun, 25

4. 即时函数能够访问全局空间的函数,支持参数传递和返回值。

//全局空间里的函数
var global_f = function()
{
alert("global scope");
};

//即时函数返回值,参数。
var result_f = (function(param)
{
alert(param); //param
global_f(); //global scope

return function()
{
return 2;
};

}("param"));

result_f(); //2

5. 即时函数也可以用于创建对象属性,比如,某个对象的某个属性在对象生命周期内都不会改变,但是该属性值的获取需要做一些工作。我们就可以通过即时函数的方式,将即时函数的返回值作为该属性的值。

//定义对象时使用即时函数
var obj =
{
msg: (function()
{
//获取该对象属性需要做的一些工作
var what = "call", who = "me";

return what + " " + who;
})(),

getMsg: function()
{
return this.msg;
}
};

6. 采用即时函数处理一些初始化任务是一个不错的方法,但是在初始化任务很复杂的情况下,采用即时函数可能导致代码凌乱,函数中可能充斥着很多零散的变量和方法。为了使初始化任务代码更加的模块化,可以采用即时对象初始化的方法。
该模式就是创建一个临时对象,创建完该临时对象后立即执行该对象的某个方法(该方法通常定义为init方法)进行初始化工作。

//即时对象初始化
({
maxwidth: 400,
maxheight: 180,
getMax: function()
{
return this.maxwidth + "x" + this.maxheight;
},
init: function()
{
//初始化任务
alert(this.getMax());
}

}).init();

7. 初始化分支,初始化分支又称为加载时分支,是一种初始化优化模式。当知道某个条件在整个程序生命周期都不会发生改变的时候,我们仅仅只需要对该条件判断一次就可以了。先看一下没有初始化分支的效果
例如:

var utils =
{
addListener: function(_el, _type, _fn)
{
if (typeof window.addEventListener === "function")
{
_el.addEventListener(_type, _fn, false);
}
else if(typeof document.attachEvent === "function") //IE
{
_el.attachEvent("on" + _type, fn)
}
else
{
_el["on" + _type] = _fn; //更早版本的浏览器
}
},

removeListener: function(_el, _type, _fn)
{
if (typeof window.addEventListener === "function")
{
_el.removeEventListener(_type, _fn, false);
}
else if(typeof document.attachEvent === "function") //IE
{
_el.detachEvent("on" + _type, fn)
}
else
{
_el["on" + _type] = null; //更早版本的浏览器
}
}
};

以上代码的问题在于,每次在调用utils.addListener或utils.removeListener时,都会重复的执行想同的检查,效率是比较低下的。


下面将采用初始化分支解决这个问题。

//接口
var util =
{
addListener: null,
removeListener: null
};

//初始化分支实现
if (typeof window.addEventListener === "function")
{
util.addListener = function(_el, _type, _fn)
{
_el.addEventListener(_type, _fn, false);
};
util.removeListener = function(_el, _type, _fn)
{
_el.removeEventListener(_type, _fn, false);
};
}
else if(typeof document.attachEvent === "function")
{
util.addListener = function(_el, _type, _fn)
{
_el.attachEvent("on" + _type, fn);
};
util.removeListener = function(_el, _type, _fn)
{
_el.detachEvent("on" + _type, fn);
};
}
else
{
util.addListener = function(_el, _type, _fn)
{
_el["on" + _type] = _fn;
};
util.removeListener = function(_el, _type, _fn)
{
_el["on" + _type] = null;
};
}

以上通过初始化分支后,util的addListener和removeListener方法只被初始化一次,以后的每次调用不必再重复的做浏览器版本判断了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值