JavaScript面向对象学习笔记——函数、匿名函数、回调函数、自调函数

来源:互联网 发布:淘宝图库官网 编辑:程序博客网 时间:2024/05/16 14:24

函数

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

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

这里写图片描述

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

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

匿名函数

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

回调函数

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

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

这里写图片描述

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

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

这里写图片描述

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

回调函数的优势

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

回调示例

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

//通过一个循环将其所接收的三个参数分别乘以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);

这里写图片描述

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

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

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

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

在以上的过程中,使用了两个循环,这是可以改进的将他们合二为一,对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);

这里写图片描述

我们还可以用匿名函数来代替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});

这里写图片描述

自调函数

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

(  function(){   alert('boo');  })()

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

(  function(name){    alert('Hello '+ name +'!');  })('dudu')

这里写图片描述


内部私有函数

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

function a(param){  function b(theinput){    return theinput*2;  };  return 'the result is ' + b(param);};

或者用函数标识记法:

var a = function(param){  var b = function(theinput){    return theinput*2;  };  return 'the result is '+ b(param);};

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

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

返回函数的函数

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

function a(){  alert('A!');  return function(){    alert('B!');  };}

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

function a(){  alert('A!');  return function(){    alert('B!');  };}var newFunc =  a();newFunc()

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

a()()

重写自己的函数

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

a = a();

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

function a(){  alert('A!');  a=function(){    alert('B!');  };}

一个综合实例:

var a = function(){  function someSetup(){    var setup = 'done';  }  function actualWork(){    alert('Worky-worky');  }  someSetup();  return actualWork;}();

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

0 0
原创粉丝点击