奇妙的JavaScript函数

四、参数

在JavaScript中调用一个函数,允许传入的实参与形参不符。具体说就是:不检查参数的个数和类型,所以JavaScript中函数的使用非常的灵活。

1.不检查实参列表

function sum(a,b) {

return a+b;

}

var result = sum(2,3);

console.log("result="+result);//5

result = sum(2,3,4);

console.log("result="+result);//5

result = sum(2);

console.log("result="+result);//NaN表示这个结果不是一个数字,但不报错

result = sum("a","b");

console.log("result="+result);//ab

 

 

2.可变参数

由于JavaScript不检查实参列表,所以JavaScript中的函数天生就支持可变参数,我们可以利用这一点实现非常高效的代码编写。

 

①形参个数

函数名.length可以返回函数声明时指定了几个形参

function sum(a,b,c) {

return a+b+c;

}

var argumentArr = [];

for(var i = 0; i < sum.length; i++) {

argumentArr[i] = i+5;

}

var result = sum(argumentArr[0], argumentArr[1], argumentArr[2]);

console.log("result="+result);

 

执行结果:

result=18

 

②实参数组

在JavaScript函数内部有一个arguments对象可以直接使用,严格来说这个对象并不是数组,但可以当做数组来用,所以通常称为伪数组。这个数组中包含了调用函数时传入的全部实参。

function superSum() {

var count = 0;

for(var i = 0; i < arguments.length; i++) {

var number = arguments[i];

count = count + number;

}

return count;

}

 

result = superSum(1,2);

console.log("superSum(1,2)="+result);

 

result = superSum(1,2,3);

console.log("superSum(1,2,3)="+result);

 

五、call()和apply()

在Java中,一个函数是不可能被任何一个对象调用的,但在JavaScript中就可以。借助函数对象自身的call()和apply()函数,函数可以被任意对象调用。

1.call()

call()函数的用法是:函数对象.call(目标对象,参数列表)

var wuDa = {

name : "武大",

showName : function(doWhat) {

//函数中的this引用的是调用这个函数的对象

console.log(this.name + "和潘金莲"+doWhat);

}

};

wuDa.showName("卖炊饼");

 

var xiMen = {

name : "西门"

};

//在JavaScript中,函数可以被其他对象调用

//函数引用.call(调用函数的对象,函数执行时需要的参数);

wuDa.showName.call(xiMen, "去马尔代夫看星星");

 

2.apply()

和call()的区别仅仅是要求传入参数要求是数组类型

var wuDa = {

name : "武大",

showName : function (wife){

console.log(this.name + "和" + wife);

}

};

var xiMen = {

name : "西门"

};

//函数对象的apply()方法,与call()函数的区别是传入的参数要求是数组类型

wuDa.showName.apply(xiMen, ["小潘潘~~~"]);

 

3.实际意义

call()和apply()在JavaScript中非常广泛的用途。

 

①遍历数组

/*

自定义的遍历数组的函数

arr参数:要遍历的数组

callBack:让每一个数组元素都调用的回调函数

*/

function myEach(arr,callBack) {

for(var i = 0; i < arr.length; i++) {

//遍历得到数组元素

var ele = arr[i];

//让数组元素调用回调函数

callBack.call(ele);

}

}

 

②参与实现继承

JavaScript中并没有类的概念,所以面向对象程序设计中的很多概念都只能模拟而没有直接的支持,“继承”就是如此。

function Person(name,age) {

this.name = name;

this.age = age;

}

//如何借助已有的Person函数简化Student函数中的重复代码?

function Student(name,age,subject) {

//this.name = name;

//this.age = age;

//借助call()函数,让Student对象调用Person()函数,这样Person()函数内部的this引用的就是Student对象

Person.call(this,name,age);

this.subject = subject;

}

//合并“子类”和“父类”的原型对象,让Student的对象是Person的实例

Student.prototype = Person.prototype;