浅谈js匿名函数

匿名函数与函数表达式

​ 与匿名函数相对的是命名函数——如果函数有名字就是命名函数,反之即为匿名函数。

​ 函数的一般定义方式为函数声明:

1
2
3
4
function 函数名(){
// 函数体
}
//调用方式为:函数名();

​ 函数的另一种定义方式:

1
2
3
4
5
var fn = function() {
// 函数体
};//由于是赋值过程所以结尾必须加分号
//调用方式为:fn();
//把一个匿名函数赋给一个变量,即为函数表达式

函数声明与函数表达式

​ 乍一看会觉得函数声明的方式来定义函数比较方便,但是函数声明和函数表达式是存在区别的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
	//函数声明
function f1() {
console.log("林深时见鹿");
}
f1();//输出“溪午不闻钟”而非“林深时见鹿”,因为f1被下面的函数声明覆盖了
function f1() {
console.log("溪午不闻钟");
}
f1();//输出“溪午不闻钟”

//函数表达式
var f2 = function () {
console.log("林深时见鹿");
};
f2();//输出“林深时见鹿”
f2 = function () {
console.log("溪午不闻钟");
};
f2();//输出“溪午不闻钟”
//函数表达式由于是变量赋值的形式,所以不存在函数覆盖的情况

匿名函数自调用

匿名函数自调用也叫做“立即执行函数”,在声明的同时立即直接执行,一次性。

​ 一般如以下两种形式:

(function (){}()); W3C建议第一种

(function (){})();

1
2
3
4
5
6
7
//函数自调用
(function () {
console.log("野竹分青霭");
}());
(function () {
console.log("飞泉挂碧峰")
})();


立即执行函数,执行后即被释放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//例子1
(function (){
var a = 123;
var b = 234;
console.log(a + b);
}());

//例子2:带参数
(function (a,b,c){
console.log(a+b+c*2);
}(1,2,3));

//例子3:有返回值
var num = (function(a,b,c,){
var d = a+b+c*2-2;
return d;
}(1,2,3));

循环添加事件时不宜使用匿名函数

在下面这个例子中要显示li的高亮,不推荐写这样的代码:

1
2
3
4
5
6
7
8
//为li添加鼠标进入事件
liObj.onmouseover = function(){
this.style.backgroundColor = "red";
};
//为li添加鼠标离开事件
liObj.onmouseout = function(){
this.style.backgroundColor = "";
};

这种匿名函数的写法不会错,但是每次循环都会产生一个匿名函数占用内存,这样子效率不高,浪费空间。

所以我们推荐在循环添加事件的时候用命名函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<script>

function my$(id){
return document.getElementById(id);
}

var kungfu = ["降龙十八掌", "黯然销魂掌", "葵花宝典", "九阴真经", "吸星大法", "如来神掌", "化骨绵掌", "玉女心经", "极乐神功", "辟邪剑谱"];

//点击按钮动态的创建列表,把列表加到div中
my$("btn").onclick = function () {
//创建ul,把ul立刻加入到父级元素div中
var ulObj = document.createElement("ul");
my$("dv").appendChild(ulObj);
//动态的创建li,加到ul中
for (var i = 0; i < kungfu.length; i++) {
var liObj = document.createElement("li");
//设置li中间的文字内容
liObj.innerHTML = kungfu[i];
ulObj.appendChild(liObj);
//为li添加鼠标进入事件
liObj.onmouseover = mouseoverHandle;
//为li添加鼠标离开事件
liObj.onmouseout = mouseoutHandle;
}
};

//此位置.按钮的点击事件的外面
function mouseoverHandle() {
this.style.backgroundColor = "red";
}
function mouseoutHandle() {
this.style.backgroundColor = "";
}

//如果是循环的方式添加事件,推荐用命名函数
//如果不是循环的方式添加事件,推荐使用匿名函数


</script>