4.4.函数的参数
在javascript中定义函数时未指定参数的类型,调用的时候也不会进行检查,甚至连传入参数的个数都不检查。不过虽然javascript不检查,但是我们最好自己检查一下,避免在执行函数的时候报错
4.4.1可选的形参
当函数被调用时传入的参数个数少于定义时的参数个数,则剩下的形参都会被设置成undefined。
var obj = {name:"tianxia",age:17};
//将对象o中可枚举的属性都放到数组a中
function getPropertyName(o,a){
if(a===undefined) a=[];
for(var property in o) a.push(property);
return a;
}
var a = getPropertyName(obj);
document.writeln(a.length);//2
getPropertyName(obj,a);
document.writeln(a.length);//4
4.4.2可变长的实参列表:实参对象
函数在被调用的时候,如果实参个数过多,则无法获得未命名值的引用。不过函数在调用时,会得到一个标识:arguments,指向实参对象的引用,类似于一个参数数组,它包含所有函数被调用时传递给他的参数,可以像调用数组一样调用他。
var sum = function(){
var i,sum = 0;
for(i=0;i<arguments.length;i++)
{
sum += arguments[i];
}
return sum;
}
document.writeln(sum(1,2,3,4,5));//15
通过它函数可以使用超过它定义的形参个数的参数,也使得构造没有参数的函数成为可能。不过通常不需要这样使用。
但是arguments不是一个真正的数组,它实际上是一个对象,恰巧包含了一组一数字为索引的元素和一个length属性。它包含一个非常重要的特性。
当一个函数包含若干形参,实参对象的数组数组元素是函数形参所对应实参的别名,实参对象已数字索引,并且形参名称可以认为是相同变量的不同命名。
function f(x) {
console.log(x); //获得x的值
arguments[0] = null; //修改实参数组对象同样会修改x
console.log(x); //输出null
}
f("shishi");
如果实参对象是一个数组的话,第二条console.log(x),将不会输出null。
4.3将对象属性用作实参
当形参个数超过三个之后,要记住实参的顺序是不太容易的。为了不让每次调用函数的时候都查阅文档,最好在定义函数是,把传入的参数都写在一对象中,在调用函数时,传入对象,对象的名/值对就是真正需要的实参数据。
// Copy length elements of the array from to the array to.
// Begin copying with element from_start in the from array
// and copy that element to to_start in the to array.
// It is hard to remember the order of the arguments.
function arraycopy(/* array */ from, /* index */ from_start,
/* array */ to, /* index */ to_start,
/* integer */ length)
{
// code goes here
}
// This version is a little less efficient, but you don't have to
// remember the order of the arguments, and from_start and to_start
// default to 0.
function easycopy(args) {
arraycopy(args.from,
args.from_start || 0, // Note default value provided
args.to,
args.to_start || 0,
args.length);
}
// Here is how you might invoke easycopy():
var a = [1,2,3,4], b = [];
easycopy({from: a, to: b, length: 4});
4.5返回
通过return结束当前函数调用,返回上一级函数。
每个返回语句都有一个返回值,没有明确表示的返回值,就会返回undefined。
如果函数以new前缀的方式被调用,且返回值不是一个对象,那么则返回this(这个新对象)!
4.6异常
javascript提供了一套异常处理机制,抛出的异常应该有一个name属性和message属性。你可以添加新的异常。
一个try只会有一个捕获所有异常catch语句,如果你需要判断异常类型来决定如何操作,那么你可以判断name属性来进行。
var add = function (a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw {
name: 'TypeError',
message: 'add needs numbers'
}
}
return a + b;
}
// Make a try_it function that calls the new add
// function incorrectly.
var try_it = function ( ) {
try {
add("seven");
} catch (e) {
document.writeln(e.name + ': ' + e.message);
}
}
try_it();