你的位置:首页 > Java教程

[Java教程]javascript 函数初探 (一)

马是函数?

所谓函数,本质上是一种代码的分组形式。我们可以通过这种形式赋予某组代码一个名字,以便与之后的调用。下面,我们来示范以下函数的声明:

function sum(a, b){  var c = a + b;  return c;  }

一般来说,函数声明通常由一下以下几部分组成:

  1. 关键词 function;

  2. 函数名称,即这里的sum;

  3. 函数所需的参数,即这里的a, b。一个函数通常具有0个或多个参数。参数之间用逗号分隔。

  4. 函数所要执行的代码块,我们称之为函数体。

  5. return子句。函数通常都有一个返回值,如果一个函数没有显式的返回值,我们就会默认他的返回值为undefined。

需要注意的是,一个函数只能有一个返回值,如果我们需要同时返回多个值,可以考虑一下把她们放进一个数组中,以数组元素的形式返回。

以上所讲的语法过程叫做函数声明。在javascript中。函数声明只是创建函数的方法之一,改天我们会介绍其她的。。。。。。。(。・_・)/~~~

    累觉不爱(。・_・)/~~~(。・_・)/~~~(。・_・)/~~~(。・_・)/~~~(。・_・)/~~~(。・_・)/~~~(。・_・)/

 

如果我们需要使用一个函数,那就必须去调用她,那就在她后面加一个用来传递参数的小括号吧!

我们来调用一下上面的函数 ======》》》》

var her = sum(1, 2);her; //返回 3

在定义一个函数的同时,我们往往会设置这个函数所需要的调用参数。当然,也可以不给她设置参数。假如您给设定了参数,在调用的时候又忘了传递参数相关的参数值,那么,javascript引擎会自动将没有传递的参数设定为undefined。

技术角度上说参数又分为形参和实参两种。

形参是指定义函数时所用的那些参数 。如sum(a, b)中的a, b。

实参是指调用函数时所传递进来的那些参数。 如上述sum(1, 2)中的1,2。

对于那些已经传递进来的参数,javascript是来这不惧的,反正我用不到的我就无视你,自动忽略。。。。,实际上我们还可以创建一些在参数方面更为灵活的函数。那就要跪谢函数内部的arguments变量了。这个变量是函数们生下来就有的,在函数中都能调用。她能返回函数所接受的所有参数。 d=====( ̄▽ ̄*)b  是不是无比强大!!!

    d=====( ̄▽ ̄*)b d=====( ̄▽ ̄*)b d=====( ̄▽ ̄*)b  

例如:

function her(){  return arguments;}her(); // 返回 [];her(1, 2, 3, true, JY); // 返回 [1, 2, 3, true, JY]

 通过arguments我们接着完善sum函数;

function sum(){   var i, res=0, nums=arguments.length;   for(var j=0; j<nums.length; j++){     res += nums[j];    }     return res; }sum(1, 2, 3);  // 6sum(1, 1, 1); // 3sum(); // 0

  1.表达式arguments.length 返回的是函数被调用时所接受的参数。但是arguments实际上不是一个数组,而是一个类似于数组的对象。(当然,实际上,在函数funcArg中,调用arguments是不必要写成funcArg.arguments,直接写arguments即可)

可以验证一下arguments是不是数组

Array.prototype.testArg = "test";function funcArg() {  alert(funcArg.arguments.testArg);   alert(funcArg.arguments[0]);}alert(new Array().testArg); // result: "test"funcArg(10);        // result: "undefined" "10"

   2.arguments对象的长度是由实参个数而不是形参个数决定的。形参是函数内部重新开辟内存空间存储的变量,但是其与arguments对象内存空间并不重叠。对于arguments和值都存在的情况下,两者值是同步的,但是针对其中一个无值的情况下,对于此无值的情形值不会得以同步。如下代码可以得以验证。

function f(a, b, c){  alert(arguments.length);  // result: "2"  a = 100;  alert(arguments[0]);    // result: "100"  arguments[0] = "qqyumidi";  alert(a);         // result: "qqyumidi"  alert(c);         // result: "undefined"  c = 2012;  alert(arguments[2]);    // result: "undefined"}f(1, 2);

  3.由JavaScript中函数的声明和调用特性,可以看出JavaScript中函数是不能重载的。

根据其他语言中重载的依据:"函数返回值不同或形参个数不同",我们可以得出上述结论:

第一:Javascript函数的声明是没有返回值类型这一说法的

第二:JavaScript中形参的个数严格意义上来讲只是为了方便在函数中的变量操作,实际上实参已经存储在arguments对象中了

另外,从JavaScript函数本身深入理解为什么JavaScript中函数是不能重载的:在JavaScript中,函数其实也是对象,函数名是关于函数的引用,或者说函数名本身就是变量。对于如下所示的函数声明与函数表达式,其实含以上是一样的(在不考虑函数声明与函数表达式区别的前提下),非常有利于我们理解JavaScript中函数是不能重载的这一特性。

function f(a){  return a + 10;}function f(a){  return a - 10;}// 在不考虑函数声明与函数表达式区别的前提下,其等价于如下var f = function(a){  return a + 10;}var f = function(a){  return a - 10;}

  4.arguments对象中有一个非常有用的属性:callee。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。

function count(a){  if(a==1){    return 1;  }   return a + arguments.callee(--a);}var mm = count(10);alert(mm); //55

arguments.callee表示引用当前正在执行的函数,或者说是调用arguments.callee的函数对象的引用,它给匿名函数提供了一种自我引用的方式。

var func = function() { alert(func === arguments.callee);}func() // true

执行上述代码,可以看到alter出来的结果是true,注意,此处用的是“===”,就是说func与arguments.callee对象类型和值都相等。

arguments.callee一般会用来同匿名函数一起使用。

再看一递归调用例子:求一个数的阶乘:

普通实现

function fun2(n) { if (n > 1) { return n * fun2(n -1); } return 1;}var r1 = fun2(3)

用匿名函数

ar r2 = (function(n) { if (n > 1) { return n * arguments.callee(n -1); } return 1;})