函数、匿名函数、回调函数、自调函数(转载)

来自https://blog.csdn.net/u012369153/article/details/69948569

在JavaScript中,函数也是一种数据类型,定义函数有两种方式:

function f(){return 1;}
var f=function(){return 1;}
  • 1
  • 2

这里写图片描述

所以,JavaScript中的函数是一种数据,但是它有两个重要的特性:

  • 包含的是代码
  • 是可执行的 
    函数的命名规则和一般变量相同,不能以数字开头、可以由任意的字母、数字、下划线组成

匿名函数

一段数据既没有赋值给某个变量,也没有被赋予任何名字就是匿名的。匿名函数的两种用法: 
- 将匿名函数作为参数传递给其他函数,接收方函数就可以利用传递过来的匿名函数完成相应的任务 
- 定义某个匿名函数来执行一些一次性任务

回调函数

定义一个以两个函数为参数的函数,该函数会分别执行这两个参数函数:

//定义一个以两个函数为参数的函数,该函数会分别执行这两个参数函数,并返回它们的返回值之和
function invoke_and_add(a,b){
  return a() + b();
}
//简单定义参与运算的函数
function one(){
  return 1;
}
function two(){
  return 2;
}
//将这两个函数传递给目标函数
invoke_and_add(one ,two);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里写图片描述

在这里我们可以用匿名函数来代替上面参与运算的两个函数,作为目标函数的参数:

function invoke_and_add(a,b){
  return a() + b();
}
invoke_and_add(function(){return 1;},function(){return 2;})
  • 1
  • 2
  • 3
  • 4

这里写图片描述

当我们将函数A传递给函数B,并且由B来执行A时,A就成了一个回调函数(callback functions),如果此时A还是一个无名函数,那么就叫它匿名回调函数。

扫描二维码关注公众号,回复: 957136 查看本文章

回调函数的优势

  • 在不做命名的情况下传递函数,这也就是说可以节省全局变量
  • 将一个函数调用委托给另一个函数,节省编码
  • 可以提高性能

回调示例

一般将一个函数的返回值传递给另一个函数。

//通过一个循环将其所接收的三个参数分别乘以2,并以数组的形式返回结果
function multiplyByTwo(a,b,c){
  var i,ar =[];
  for(i=0;i<3;i++){
    ar[i] = arguments[i]*2;}
  return ar;
}
//只接受一个参数,将它加1后并返回
function addOne(a){
  return a+1;
}
multiplyByTwo(1,2,3);
addOne(100);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这里写图片描述

接下来,我们实现这三个元素在两个函数之间的传递,在这定义一个用于存储元素的数组,先从multiplyByTwo()的调用开始

var myarr = [];//定义一个数组
myarr =  multiplyByTwo(10,20,30);//调用函数
  • 1
  • 2

然后,用遍历循环每个元素,并将它们分别传递给addOne()

for(var i=0;i<3;i++){
 myarr[i] = addOne(myarr[i]) 
}
myarr
  • 1
  • 2
  • 3
  • 4

在以上的过程中,使用了两个循环,这是可以改进的将他们合二为一,对multiplyByTwo()函数改为接收一个回调函数,并在每次迭代操作中调用它:

function multiplyByTwo(a,b,c,callback){
  var i,ar =[];
  for(i=0;i<3;i++){
    ar[i] = callback(arguments[i]*2);
  }
  return ar;
}
function addOne(a){
  return a+1;
}
myarr = multiplyByTwo(1,2,3,addOne);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里写图片描述

我们还可以用匿名函数来代替addOne(),这样可以节省一个额外的全局变量

function multiplyByTwo(a,b,c,callback){
  var i,ar =[];
  for(i=0;i<3;i++){
    ar[i] = callback(arguments[i]*2);
  }
  return ar;
}

myarr = multiplyByTwo(1,2,3,function(a){return a+1});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里写图片描述

自调函数

匿名函数的另一个应用,可以在定义后自行调用。

(
  function(){
   alert('boo');
  }
)()
  • 1
  • 2
  • 3
  • 4
  • 5

只需要将匿名函数的定义放进一堆括号中,然后外面再紧跟一对括号即可,第二个括号的作用是“立即调用”的意思,同时也是向匿名函数传递参数的地方。

(
  function(name){
    alert('Hello '+ name +'!');
  }
)('dudu')
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述


内部私有函数

在一个函数内部定义另一个函数。

function a(param){
  function b(theinput){
    return theinput*2;
  };
  return 'the result is ' + b(param);
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

或者用函数标识记法:

var a = function(param){
  var b = function(theinput){
    return theinput*2;
  };
  return 'the result is '+ b(param);
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当我们调用全局函数a()时没,本地函数b()也会再其内部被调用,由于b()是本地函数,它在a()以外的地方是不可见的,所以称它为私有函数。它的优势有:

  • 有助于确保全局名字空间的纯净性(就是命名冲突的几率小)
  • 私有性——可以选择只将一些必要的函数暴露给外部,并保留属于自己的函数,使得它们不能被程序的其他部分所用

返回函数的函数

函数始终都会有一个返回值,即便不是显式返回也会隐式返回一个undefined。既然函数能返回一个唯一的值,那么这个值也有可能是另一个函数:

function a(){
  alert('A!');
  return function(){
    alert('B!');
  };
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

函数a()会在执行说A之后返回另一个函数b(),而b()又会去执行另外一些事情说B,我们吧该返回值赋值给某个变量,然后就可以向向使用一般函数一样调用它了。

function a(){
  alert('A!');
  return function(){
    alert('B!');
  };
}
var newFunc =  a();
newFunc()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述 
这里写图片描述 
如执行结果所示,第一行执行的是A,第二行是B,若是想让返回的函数立即执行,也可以不用将它赋值给变量,直接在该调用函数再加一对括号就可以:

a()()
  • 1

重写自己的函数

一个函数可以返回另一个函数,因此可以用新的函数来覆盖旧的函数,比如上个例子,可以通过a()的返回值来重写a()函数自己。

a = a();
  • 1

当前这句依然只会执行alert(”A!”),但是我们再次调用a(),就会执行alert(“B!”)了。我们也可以让函数从内部重写自己:

function a(){
  alert('A!');
  a=function(){
    alert('B!');
  };
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

一个综合实例:

var a = function(){
  function someSetup(){
    var setup = 'done';
  }
  function actualWork(){
    alert('Worky-worky');
  }
  someSetup();
  return actualWork;
}();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这个函数中使用了私有函数:someSetup()和actualWork() 
使用了自调函数:函数a()的定义后面有一对括号,会执行自行调用。 
当该函数第一次被调用时,会调用someSetup()函数,并返回函数变量actualWork的引用,注意返回值是不带括号的,因此这个结果仅仅是一个函数的引用,并没有执行函数不会产生函数调用。这里执行的语句是以var a = 开头的,因而该自调函数所返回的值会重新赋值给a


猜你喜欢

转载自blog.csdn.net/qq_20834787/article/details/79807144