JavaScript:函数相关

return 语句
函数可以有return语句,也可以没有return语句。return语句能够使函数停止运行,并且把表达式的值(如果存在这样的表达式)返回给函数调用者。如果return语句没有一个相关的表达式,它会返回undefined值。如果函数不包含return语句,它就执行函数体中的每条语句,然后返回给调用者undefined。

可变长度的参数列表:Arguments对象

在函数体内,标识符arguments具有特殊含义。它是引用arguments对象的一个特殊属性。Arguments对象是一个类似数组的对象,可以按照数目获取传递给函数参数值。
Arguments允许完全的存取那些实际参数值,即使某些货全部参数还没有被命名。
和真正的数组一样,arguments具有length属性。
验证调用函数时是否使用了正确数目的实际参数。

function f(x,y,z){
    if(arguments.length != 3){
        alert("需要三个参数");
    }
    //code.....
}

函数可以接受任意多的实际参数

function max(){
    var m=0;
  for(var i = 0;i<arguments.length;i++){
      if(arguments[i] > m) m = arguments[i];
   }
    return m;
 }

max(1,10,2,3,4,5,6);

记住!!!!!!!arguments并非真正的数组,它是Arguments的一个对象。虽然每个Arguments对象都定义了带编码的数组元素和length属性,但是它不是数组。将它看作偶然具有了一些带编码的属性的对象更合适一些。

当函数具有了命名的参数时,Arguments对象的数组元素是存放函数参数的局部变量的同义词。arguments[]数组和命名了的参数不过是引用了同一变量的两种不同的方法。相反,用参数名改变一个参数的值同时会改变arguments[]数组获得的值。通过arguments[]数组改变参数的值同样会改变用参数名获取的值。

function f(x){
    alert(x);
    arguments[0] = null;
    alert(x);
}

f(1);   //先alert出 1 后alert出 null

如果Arguments对象是一个普通的数组,这肯定是不能所见到的行为。在这个例子中,arguments[0] 和 x 最初都引用相同的值。

属性callee

除了数组元素,Arguments对象还定义了callee属性,用来引用当前正在执行的函数。这个属性没什么太大用处,但它可以用来允许对未命名的函数递归地调用自身。

function (x){
    if(x<=1)
        return 1;
    else
        return arguments[0].callee(x-1);
}

作为数据的函数

function square(x){
    return x*x;
}

这个定义创建了一个新的函数对象,并且把这个对象赋予了变量square。实际上,函数名并没有实质意义,它不过是用来引用函数变量的名字。可以将这个函数给其他的变量,它仍然会以相同的方式起作用。

var a = square(4);
var b = square;
var c = b();

除了赋给全局边变量外,还可以将函数赋给对象的属性。在这种情况下,我们称之为方法。

var o = new Object;
o.square = function(x){
    return x*x;
}
y = o.square(16)
function add(x,y){return x+y};
function subtract(x,y){return x-y};
function multiply(x,y){return x*y};
function divide(x,y){return x/y};

function operate(operator,num1,num2){
   return operator(num1,num2);
}

var i = operate(add,operate(add,2,3),operate(multiply,4,5));
//计算(2+3)+(4*5)

在上面的例子代码中,以operate(add,2,3)为例,第一个参数是add,持有function add 的引用,传递给operator,所以operator(2,3),相当于add(2,3)。正如上面说到的,可以把函数的引用以函数名的形式赋值给别的变量,该变量也持有了那个函数的引用。

var operators = {

  add :function (x,y){return x+y},
  subtract:function (x,y){return x-y},
  multiply:function (x,y){return x*y},
  divide:function (x,y){return x/y},
  pow:Math.pow

}

function operate(op_name,num1,num2){
   return operators[op_name](num1,num2);
}

var i = operate("add","Hello",operate("add"," ","World"));
alert(i);//  Hello World

作为方法的函数
方法有一个非常重要的属性:在方法中,用来调用方法的对象成为关键字this的值。

var calculator = {
  op1:1,
  op2:1,
  compute : function(){
   return this.result = this.op1+this.op2;
  }
}

calculator.compute();

这个this关键字很重要。任何用作方法的函数都被有效地传递了一个隐式的参数,即调用函数的对象。
当一个函数作为函数而不是方法调用的时候,这个this关键字引用全局对象。

函数的属性和方法
length
arguments数组的length属性指定了传递给函数的实际参数数目。但是函数本身的length属性的含义却并非如此,它只是只读性,返回的是函数需要的实际参数的数目,也就是在函数的形式参数列表中声明的形式参数。

function check(args){
  var actual = args.length;
  //获得当前运行函数的应该有的参数数目
  var expected = args.callee.length; 
  if(actual != expected){
    throw new Error("error");
  }
}
function f(x,y,z){
  check(arguments);
  return x+y+z;
}

f(1,2)   //会输出error信息

方法apply()和call()
ECMAScript规范给所有函数定义了两个方法call()和apply().使用这两个方法可以像调用其他对象的方法一样调用函数。call()和apply()的第一个参数都是要调用的函数的对象,在函数体内这一参数是关键字this的值。例如,要把两个数字传递给函数f(),并将它作为对象o的方法调用,可以使用如下代码:

f.call(o,1,2);

这与下面的代码相似:

o.m = f;
o.m(1,2);

apply()和call()很相似,只不过要传递给函数的参数是由数组指定的:

f.apply(o,[1,2]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值