新手小白对回调函数的理解
只是写写自己的理解,借鉴了网上的一些文章,欢迎指正!
1.什么是函数
要了解回调函数,就必须先了解函数。那么,什么是函数呢?
如果要多处实现某个功能,不用函数的话就要写很多次,增加代码量,浪费时间;如果要修改这个功能,那就要多处修改,非常不方便。使用函数可以减少代码量,方便后期修改。
在JavaScript 中定义函数的方法有 3 种,即使用 function 语句、使用 Function() 构造函数和定义函数直接量。
(1)使用 function 语句声明函数。具体用法如下:
function onDeleteMail ( [args] ) {
//statements
}
onDeleteMail 是函数名,与变量名一样必须是 JavaScript 合法的标识符。在函数名之后是一个由一个小括号包含的参数列表,参数之间以逗号分隔。参数是可选的,没有数量限制。
作为标识符,参数仅在函数体内被访问,参数是函数作用域的私有成员。调用函数时,通过为函数传递值,然后使用参数获取外部传入的值,并在函数体内干预函数的运行。
在小括号之后是一个大括号,大括号内包含的语句就是函数体结构的主要内容,大括号是必不可少的,缺少大括号,JavaScript 将会抛出语法错误。
function 语句必须包含函数名、小括号和大括号,其他代码都可省略,因此最简单的函数体是一个空函数。
function onDeleteMail( ) { } //空函数
如果使用匿名函数,则可以省略函数名。
function ( ) { } //匿名空函数
var 语句和 function 语句都是声明语句,它们声明的变量和函数都在 JavaScript 预编译时被解析,也被称为变量提升和函数提升。在预编译期,JavaScript 引擎会为每个 function 创建上下文,定义变量对象,同时把函数内所有形参、私有变量、嵌套函数作为属性注册到变量对象上。
(2)Function() 构造函数// 此方法并不常用
使用 Function( ) 构造函数可以快速生成函数。具体用法如下:
var boy = new Function (p1 , p2 , ... , pn , body) ;
Function( ) 的参数类型都是字符串,p1~pn 表示所创建函数的参数名称列表,body 表示所创建函数的函数结构体语句,在 body 语句之间以分号分隔。
使用 Function( ) 构造函数可以不指定任何参数,创建一个空函数结构体。
var f = new Function( ); //定义空函数
使用 Function() 构造函数可以动态的创建函数,它不会把用户限制在 function 语句预声明的函数体中。使用 Function() 构造函数能够把函数当做表达式来使用,而不是当做一个结构,因此使用起来会更灵活。其缺点就是,Function() 构造函数在执行期被编译,执行效率非常低,一般不推荐使用。
(3)匿名函数(函数直接量)
函数直接量也称为匿名函数,即函数没有函数名,仅包含 function 关键字、参数和函数体。具体用法如下:
function ( [args] ) {
// statements
}
示例1:
下面代码定义一个函数直接量。
//函数直接量
function ( a , b ){
return a+b;
}
在上面代码中,函数直接量与使用 function 语句定义函数结构基本相同,它们的结构都是固定的。但是函数直接量没有指定函数名,而是直接利用关键字 function 来表示函数的结构,这种函数也被称为匿名函数。
示例2:
匿名函数就是一个表达式,即函数表达式,而不是函数结构的语句。下面把匿名函数作为一个值赋值给变量 f。
//把函数作为一个值直接赋值给变量 f
var f = function ( a, b){
return a+b;
};
当把函数结构作为一个值赋值给变量之后,变量就可以作为函数被调用,此时变量就指向那个匿名函数。
console.log ( f ( 1,2 ) ); //返回值3
示例3:
匿名函数作为值,可以参与更复杂的表达式运算。针对上面示例可以使用以下代码完成函数定义和调用一体化操作。
//把函数作为一个操作数进行调用
console.log(
( function(a,b) {
return a+ b;
})(1,2)); //返回数值3
(4)定义嵌套函数
JavaScript 允许函数相互嵌套,因此可以定义复杂的嵌套结构函数。
示例1:
使用 function 语句声明两个相互嵌套的函数体结构。
function f (x,y) { //外层函数
functione (a,b){ //内层函数
return a*b ;
}
return x+y;
}
示例2:
嵌套的函数只能在函数体内可见,函数外不允许直接访问、调用。
function f (x,y) {
function e (a,b) {
return a*b;
}
return e (3, 6) + y; //内层函数参与表达式运算有效
console.log (e (3,6) ); //无效的调用
}
console.log ( f (3,6) ) ; //调用外层函数
2.什么是回调函数
回调函数就是一个被作为参数传递给另一个函数,回调函数早另一个函数中被调用。众所周知,函数被大量使用的原因即为:一段代码需要被多处调用,将此段代码封装至一个函数体内,可在多处调用,减少代码量。而回调函数是为了解决多处调用时,后续操作的不同。比如说,周五了老师给同学们布置作业,老师可以选择分别给每一个同学布置一遍作业,也可以将同学们聚到一起,一次就把作业布置完成。这就像一个函数,封装一次,多次使用。但是老师把作业布置好以后。每个学生会用自己的方式完成,可能有些学生周五全部写完,有些同学攒到周天才写作业,这就是回调函数。
那么什么时候回调函数会进行调用吗?
① 发生事件时,例如,用户单击按钮,或者用户从下拉列表中选择某些选项等等。
示例:DOM事件回调函数
documet . getElementById ('btn') .onclick = function( ){
alert 'hello world' ;
};
② 定时器回调函数
setTimeout ( function( ){
console.log('两秒过去了');
} , 2000 );