javascript中的function可以用来创建方法、也可以用来创建类,实际上我们可以认为是用function来模拟出的类(说到类一般都会要去了解闭包的知识)。还是先看一下方法吧。
javascript函数分为有名函数、匿名函数和在匿名函数基础上延伸出来的立即执行函数。
普通函数就是用function直接声明的有名函数。
代码如下 |
复制代码 |
function Hello() {
alert("hello , everybody!");
};
Hello();
function SayHelloTo(somebody) {
alert("hello , " + somebody + "!");
};
SayHelloTo("张三");
|
上面分别创建了Hello和SayHelloTo方法。Hello不带有参数,直接通过Hello()来完成调用。SayHelloTo方法带有一个参数,向谁问候时需要知道是在问候谁。在调用SayHelloTo(“张三”)时要传入参数。这些代码和java、C#都没有什么太大区别。在方法重载上却有较大改变,javascript本身并不支持什么重载,一个方法名就对应一个方法。如果强制的写出多个同名方法,其实会出现先写的方法被覆盖掉的情况。
代码如下 |
复制代码 |
function Hello() {
alert("hello , everybody!");
};
Hello();
function Hello(somebody) {
alert("hello , " + somebody + "!");
};
Hello("张三");
|
第一个Hello方法被覆盖掉,执行时直接调用Hello()则认为调用第二个Hello方法但没有传递参数值,所以弹出了undefined信息。调用Hello(“张三”)时很正常的完成执行。其实javascript也可以用一些直白的方式来完成重载。学过C#的人都会知道有个params关键字,通过它可以实现向方法传递不定个数的参数。我们可以通过对参数的信息做手动的判断也可以模拟出类似重载的效果。而在javascript中根本就不需要什么params关键字,就可以很自然的实现任意个数参数的传递。function中有个arguments属性,可以把它看成一个数组,它按传递进来的参数的顺序来保存所有的参数。也就是说我们在定义方法时可以不声明参数名。
代码如下 |
复制代码 |
function ShowArguments() {
var args = "";
for (var i = 0; i < arguments.length; i++) {
args += arguments[i] + ",";
};
alert(args.substr(0, args.length - 1));
};
ShowArguments(1, 2, 3, 4, 5, 6, 7);
|
试着用argements来模拟一下重载。
代码如下 |
复制代码 |
function Hello() {
if (arguments.length == 0) {
alert("hello , everybody!");
}
else {
alert("hello , " + arguments[0] + "!");
};
};
Hello();
Hello("张三");
|
基于参数个数不同的重载。
代码如下 |
复制代码 |
function Increase(arg) {
if (typeof arg == "undefined") {
alert("请输入参数");
}
if (typeof arg == "string") {
alert(String.fromCharCode(arg.charCodeAt(0) + 1));
}
if (typeof arg == "number") {
alert(arg + 1);
}
};
Increase();
Increase("a");
Increase(1);
|
基于参数类型不同的重载。
函数除了有名函数之外也可以是匿名函数,匿名函数就是没有名子的函数,不论函数有名还是没有名子,都是一个完整的函数对象。匿名函数还是用function来声明,但不用为它指定名称。其它的方面,比如参数等等和有名函数没什么区别。
代码如下 |
复制代码 |
function() {
……
};
|
匿名函数一般可以满足临时的函数需求,不需要有变量对其进行引用(有名的函数可以认为是有变量引用的函数)。比如需要一个函数做为值对象做为参数传入方法、需要编程的方式为对象添加事件,用匿名函数都可以很好的完成。当然你也可以单独声明变量来引用某个匿名函数对象,这和普通有名函数就没什么区别了。
代码如下 |
复制代码 |
function Each(array, fun) {
for (var i = 0; i < array.length; i++) {
fun(array[i]);
};
};
var nums = [1, 2, 3, 4, 5, 6, 7];
Each(nums, function(arg) {
alert(arg);
});
|
上面代码执行,依次输出数组中的元素。
代码如下 |
复制代码 |
//在窗体加载时,在标题上显示当前时间
window.onload = function() {
document.title = new Date().toString();
};
//也可以将匿名方法传入定时器中
setInterval(function() {
document.title = new Date().toString();
}, 1000);
|
使用匿名函数绑定事件和进行定时操作。
代码如下 |
复制代码 |
var Hello = function() {
alert("hello , everybody!");
};
|
如果将匿名函数赋给变量,那和有名的普通函数就没区别了。但不管是变量引用还是普通地有名函数,这样的函数在内存上都持久的占有一定资源。有时候我们只想执行一次大不必使用有引用的函数,直接执行匿名函数可能是最好的选择。把匿名函数包起来,加个括号执行,一切ok,这就是由匿名函数延伸出来的立即执行函数。
代码如下 |
复制代码 |
(function() {
alert("hello , everybody!");
})();
(function(somebody) {
alert("hello , " + somebody + "!");
})("张三");
|
立即执行函数在做事件绑定,设置回调函数等方面往往会有意想不到的效果,可以解决诸如对象引用等问题。
代码如下 |
复制代码 |
var student = {
Name: "张三",
Age: 20,
Introduce: function() {
alert("我叫" + this.Name + ",今年" + this.Age + "岁了!");
} };
window.onload = (function(obj) { return function() { obj.Introduce(); }; })(student); |
因为javascript中函数的这些特点加之它的对象的特征,我们还可以写出一些有functional意味的程序出来。其实javascript中function真的是老大。
代码如下 |
复制代码 |
function Sum(fun, x) {
if (x <= 0)
return 0;
return fun(x) + Sum(fun, x - 1);
};
alert(Sum(function(i) { return i * i; }, 100));
|
使用function一些问题:function的参数问题 .
.当传入的参数个数小于声明的参数个数时,缺少的参数值就是:undefined
代码如下 |
复制代码 |
function ReciveParam(/*第一个参数*/a,/*第二个参数*/b)
{
alert("a:"+a);// display:a:第一个参数
alert("b:"+b); // display:b:undefined
}
function GiveParam()
{
ReciveParam("第一个参数");
}
|
2..函数中可以通过arguments对象来获取函数的全部参数
代码如下 |
复制代码 |
function show()
{
var largest=Max(10,20,30,1,10000,88,56,123);
alert(largest);//display:10000
}
function Max(m)
{
var re=0;
for(var i=0;i<arguments.length;i++)
{
if(arguments[i]>re)
{
re=arguments[i];
}
}
return re;
}
|
Arguments对象是一个类似于数组的对象,可以按照参数的数目而不是名称来获取全部参数,并且arguments也具有length属性,可以用来获取获取实际参数的个数.
arguments虽然具有一些数组的特性,但是他不是数组.实际上arguments[]是和实际参数是引用同一变量的两种方法:
代码如下 |
复制代码 |
function ChangeParamValue()
{
ChangParamValueDo("第一个参数","第二个参数");
}
function ChangParamValueDo(a,b)
{
alert("改变前:a:"+a+",b:"+b);// display:改变前:a:第一个参数,b:第二个参数
arguments[0]="arguments0";
arguments[1]="arguments1";
alert("用arguments改变后:a:"+a+",b:"+b); // display:用arguments改变后:a:arguments0,b:arguments0
}
|
arguments有一个callee属性,用没过来引用当前正在执行的函数
代码如下 |
复制代码 |
function f(x)
{
if(x<=1) return x;
return x*arguments.callee(x-1);
}
|
3。把对象属性用作参数:这样可以不必去记参数的顺序,用对象的属性名来传参
代码如下 |
复制代码 |
function ArrayCopy(name,age,grade,sex,height,weiht)
{
alert("name:"+name+" age:"+age+" grade:"+grade+" sex:"+sex+" height:"+height+" weiht:"+weiht);
}
function EasyCopy(args)
{
ArrayCopy(args.name||"",
args.age||0,
args.grade||"one",
args.sex||"可选",
args.height||100,
args.weight||100 )
}
function show()
{
EasyCopy({name:'lily',age:'13',grade:'three'});
EasyCopy({name:'mark',height:'180',weight:180});
}
|
|