5.1函数的定义有3种方式:声明式函数,匿名函数和函数直接量。
通过匿名函数可以使用户来定义函数的函数体:其中最后一个参数是函数体,前面的都是函数的参数。
var func = prompt("输入函数"); var x = prompt("输入x的值:"); var y = prompt("输入y的值:"); var op = new Function("x","y","return "+func); var theResult = op(x,y); document.writeln("Function is " + func + "<br />"); document.writeln("x is " + x + "<br />y is " + y + "<br />"); document.writeln("The answer is " + theResult);
Function is x + "哈哈" +y
x is 我
y is 你
The answer is 我哈哈你
function foo(x,y,z){ alert(z(x,y)); } foo(3,2,function(x,y){return x*y;})
上例定义了一个函数foo,函数的第3个参数(z)本身又是一个函数,而foo的功能是调用函数z,将前两个参数传给它。
如果再调用的时候传入不同的函数,可以获得不同的结果。
不必非得使用函数构造函数来创建一个函数然后再把它赋给一个变量;它直接就能成为一个函数直接量。
var func = function (params){ statements; }
函数直接量也被叫做函数表达式,因为函数是作为表达式的一部分而创建的,而不是一个专门的语句类型。它们与匿名函数类似,两者都没有指明函数名。然而与匿名函数不同的是,函数直接量只解析一次,实际上,除了函数被赋给了一个变量之外,函数直接量更类似于声明式的函数。
var func = function(params){
statements;
}
func(params);
函数直接量的第2种形式是非匿名的,即指定了函数的名称:但是这个名字只能在函数自己的内部访问,这可以在实现递归函数时候用到。
var func = function foo(params){
statements;
}
5.2 回调函数
function checkColor(element,index,array){ return (element>=0 && element<256); } function checkCount(element,index,array){ return(element.length == 3); } var colors = new Array(); colors[0] = [0,262,255]; colors[1] = [255,255,255]; colors[2] = [255,0,0]; colors[3] = [0,255,0]; colors[4] = [0,0,255]; colors[5] = [-5,999,255]; var testedColors = new Array(); for(var i in colors){ testedColors[i] = colors[i].filter(checkColor); } for(i in testedColors){ document.writeln("test " + testedColors[i] + "<br />"); } var newTested = testedColors.filter(checkCount); for(i in newTested){ document.writeln(newTested[i] + "<br />"); }
输出:
test 0,255
test 255,255,255
test 255,0,0
test 0,255,0
test 0,0,255
test 255
255,255,255
255,0,0
0,255,0
0,0,255
只有4个颜色通过了两项检查。
但是还是不明白为什么叫回调函数。
看到的CSDN的一个分析,感觉看明白了,但是看回js又不明白了。
使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。
—— 某专家
回调函数,就是由你自己写的。你需要调用另外一个函数,而这个函数的其中一个参数,就是你的这个回调函数名。这样,系统在必要的时候,就会调用你写的回调函数,这样你就可以在回调函数里完成你要做的事。
—— 绿叶
#include <stdio.h> void printWelcome(int len) { printf("欢迎欢迎 -- %d/n", len); } void printGoodbye(int len) { printf("送客送客 -- %d/n", len); } void callback(int times, void (* print)(int)) { int i; for (i = 0; i < times; ++i) { print(i); } printf("/n我不知道你是迎客还是送客!/n/n"); } void main(void) { callback(10, printWelcome); callback(10, printGoodbye); printWelcome(5); }
那么如何自定义一个回调函数呢?
举个小例子:
想要执行一个加法运算操作,在加操作执行完毕,我们还想要将这个加的结果作一个2倍操作,并返回最终值
function double(data){return data*2;}
function add(a,b,double){var sum = a+b; return double(sum);}
5.3 函数和递归
var addNumbers = function sumNumbers(numArray,indexVal,resultArray){ if(indexVal == numArray.length) //递归完成时,返回结果序列 return resultArray; //数值增加 //使用Number转换数值类型 resultArray[0] += Number(numArray[indexVal]); if(resultArray[1].length > 0) resultArray[1] += " and "; //记录数组中使用的数字 resultArray[1] += numArray[indexVal].toString(); //递归层数递增 indexVal++; //call function again,return results //递归没有完成时,顺序向下执行到调用自己本身 return sumNumbers(numArray , indexVal , resultArray); } //create numeric array , and the result array var numArray = ['1',35.4,'-13','44','0.5']; var resultArray = new Array(0,''); var result = addNumbers(numArray , 0 , resultArray); document.writeln(result[0] + "<br />"); document.writeln(result[1]);
输出:
67.9
1 and 35.4 and -13 and 44.00 and 0.5
Number()的强制类型转换与parseInt()和parseFloat()方法的处理方式相似,只是它转换的是整个值,而不是部分值。parseInt()和parseFloat()方法只转换第一个无效字符之前的字符串。如“3.4.5”被转换成“3.4”, 用Number()进行强制类型转换将返回NAN, 如果字符串值能被完整地转换,Number()将判断是调用parseInt()还是parseFloat()。