JS函数
函数是JS中的一等公民,平常JS的使用基本上都是和函数打交道。JS中的函数也可以看作是一个类(同时也是该类的构造器),函数本身也是一个对象,它是function的实例。
1:函数的定义
JS是弱类型语言,不需要对参数、返回值进行类型的声明。
方式1:有函数名。
function functionName(parameter-list){
....;
}
方式2:匿名函数
var f = function(parameter-list){
....;
};
如上,定义了一个匿名函数,实际上就是定义了一个函数对象(即Function类的实例),然后把对象赋给了一个变量f。
这种方式也是推荐使用的方式。
当然,方式1的定义也可以赋给一个变量,意味着原本的函数名不可用了。
方式3:使用Function类匿名函数
var f = new Function(parameter-list,"函数执行体");
例:
var a = new Function("name", "document.writeln("你好"+name);");
2:局部函数
如同JS的局部变量,局部函数只能在函数中进行访问。
3:函数、方法、对象、变量和类
函数在JS中不仅仅意味着函数,当使用JS定义一个函数时,可以理解为出现了以下这么多玩意:
a:函数:这个不必说,也可以理解为Java中的方法。java中的方法需要对象或类来调用,这里的函数也是被调用(省略调用对象时,默认对象就是window)。
b:对象:定义函数时,系统也会创建一个对象,该对象是Function类的实例。如下代码:
var hello = function(name){
return name+"你好";
}
alert((hello instanceof Function)+" "+
(hello instanceof Object)); //会显示两个true;
alert(hello); //会显示函数代码
c:方法:就像前面a说到的,定义函数时通常会附加给某个对象,作为对象的方法存在。默认对象就是window对象。调用函数时可以看作是方法调用,window对象可以省略。
d:变量:定义函数是,同时也会得到一个变量。比如:
function hello (name) {
return "fuck"+name;
}
hello = "12345"; //此处hello函数就被销毁了,被字符串变量覆盖了。
e:类:定义函数时,也就是定义了一个同名的类,同时也是唯一的构造器。如下代码:
var test = function(name){
return "你好"+name;
};
var f1 = test("aaa"); //直接调用函数的话,得到的是函数的额返回值。
var f2 = new test("bbb"); //通过new调用的话,得到的是函数的对象。
4:函数的属性和方法
既然函数可以看作为一个类,那么就可以有变量(属性)和方法。如下代码:
function person(name, age){
this.name = name;
person.age = age;
var bb = 0;
this.info = function(){ //此处就是定义了一个方法。
document.writeln("我的名字是:"+this.name");
}
}
当使用此函数(类)时,可以:
var p = new person(“aaa”,22);
p.info();
此时也就完成了方法调用。
这里的this关键字代表着实例属性和实例方法,而是用函数名作为前缀则是类属性和类方法(如同Java中的static关键字定义)。
函数中var定义的变量为局部变量。局部变量不能再函数外引用,这点就不用多说了。
5:通过call()方法和apply()方法调用函数
形式:函数引用.call(调用者,参数1,参数2);= 函数引用.apply(调用者,参数1,参数2); = 调用者.函数(参数1,参数2);
6:函数提升
只需要知道,使用函数名定义的函数,可以在定义之前调用。
而是用匿名定义的函数,则不能提前调用。
函数内的内部函数,如果赋值给不使用var声明的变量,则该变量就是一个全局变量,其代表的函数也成了全局函数。
如同JS的变量提升。能不用就不用。
7:箭头函数
如同Lambda表达式,是函数的简化写法。
(param1,param2...) => \{ statements \}
如果函数体中只有一条return 语句,则允许省略花括号和return关键字。
如果参数列表中只有一个参数,则允许省略列表的圆括号。
8:函数的参数传递:
基本类型以及复合类型(数组,对象函数)的参数传递,都采用值传递方式,传入的都是参数的副本。只不过复合类型本身就是一个引用,传入的参数也是一个引用,它们指向同一个对象,因此函数内对复合类型参数的修改会影响函数外的复合类型。
JS中,如果函数定义有参数,实际调用可以没有参数,因为系统会自动赋值为undefined。也就意味着,JS没有所谓的函数重载,因为即使定义函数声明了多个形参,调用时可以不用完全匹配。
函数唯一重要的是函数名。如果先后定义两个同名的函数,后面的会把前面的函数覆盖掉。
9:参数类型
由于是弱类型语言,函数的形参无需声明类型。这就会导致一些问题。如:
function changeAge(p){
p.setAge(20);
}
这时调用时完全有可能传入的是其他类型的参数,就会导致错误。
所以,建议使用参数判断来进行操作。参数判断使用typeof或者instanceof。如下:
function changeAge(p){
if(typeof p == 'object' && tyoeof p == 'number'){
执行体...
}else{
执行体...
}
}
还没有评论,来说两句吧...