你的位置:首页 > Java教程

[Java教程]对js中function的浅见


它到底是什么

String Array 都是系统内置对象(已经定义好,可以直接使用)当然,这货也是一样,我们之前定义的函数,其实就是一个这货的实例。

在JS中,所有的对象都是由函数实现的,函数的数据类型是object。So,我们以前定义的函数也是一个对象。

 

几种写法

 1 function fn1(a,b){ 2  return a+b; 3  } 4  5  //前面表示参数,后面表示函数语句 6  var fn2 = new Function("a","b","return a+b"); 7  8  // 匿名函数 9  var fn3=function(a,b){10   return a+b;11  }12 13 14  console.log(fn1(1,2));15  console.log(fn2(1,2));16  console.log(fn3(1,2));  // 注意,一定要在声明函数的后面调用

 

另外,如果函数没有明确的返回值,或者调用了没有参数的return,那么它真正返回的值是undefined

 1 function fn(){ 2  //..... 3 } 4  5  6 function fn1(){ 7  return; 8 } 9 10 11 console.log(fn()===undefined); // true12 console.log(fn1()===undefined); // true

 

arguments  

arguments只有在代码运行的时候才起作用,它是一个数组(准确的说是伪数组),保存函数的参数。

 1 function fn(){ 2   var sum=0; 3   for(var i=0;i<arguments.length;i++){ 4     sum+=arguments[i]; 5   } 6   return sum; 7  } 8  9  var sum = fn(1,2);10  var sum2 = fn(1,2,3);11  console.log(sum);   // 312  console.log(sum2);   // 613 14  function fn1(a,b,c,d){15    console.log(arguments.length);16    console.log(arguments[0]);17  }18 19  fn1();          // 0 、 undefined20  fn1(1);          // 1 、 121  fn1('a',2);        // 2 、 a22  fn1('李志',2,3);     // 3 、 李志23  fn1('李B',2,2,3,4,4);   // 6 、 李B

 

Length

我们需要了解两个东东,形参与实参(不同的资料书籍可能叫法有所差异)

形参:函数定义的时候的参数  实参:调用函数的时候传递的参数

length指的是形参个数   arguments.length指的是实参个数

1 function fn(a, b) {2   console.log(fn.length);3   console.log(arguments.length);4  }5 6 fn(1, 2); // 2  27 fn(1);   // 2  1

 

call  apply

1,借用另一个对象的方法  2,替换this指向

Apply方法  调用函数,并用指定对象替换函数的this值,同时用指定数组替换函数的参数。

Call方法    调用一个对象的方法,用另一个对象替换当前对象。

 1   //对象1 2   var obj1={ 3     getAllStudentsNumbers:function(sum,sum1){ 4       return sum+sum1} 5   }; 6  7   //对象2 8   var obj2={ 9     getDetail:function(){10       return {name:'阿拉三',age:'18'}11     }12   };13   console.log(obj1.getAllStudentsNumbers.call(obj2,10,200));   // 21014   console.log(obj1.getAllStudentsNumbers.apply(obj2,[10,200]));  // 210

Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)

 

我们通过如下方式将其转换成数组

1 /* slice : 截取数组,返回的还是数组,这里我们截取全部 */2 var divs = document.getElementsByTagName("div")3 var domNodes = Array.prototype.slice.call(divs);

还可以实现继承,在上篇文章中说过,这里不做赘述。

 

caller callee

caller属性 获取调用当前函数的函数。caller属性只有当函数正在执行时才被定义。

返回函数调用者,主要用于察看函数本身被哪个函数调用.

 1   function fn() { 2     //判断某函数是否被调用 3     if (fn.caller) { 4       alert(fn.caller.toString()); 5     } else { 6       alert("函数直接执行"); 7     } 8   } 9 10   function fn1() {11     fn();12   }13   fn1();14   fn();

 

callee属性 返回正被执行的 Function 对象,即指定的Function 对象的正文。

如下是一个递归算法 - 计算 1+2+3+4+...+n

什么是递归?    可以这样理解,一个方法,自己调用自己,用上一次调用得出的结果作为这次的参数。

传统方式的缺点:

1、破坏了,零重复法则,当一旦函数名称更改,需要更改多处

2、fn是一个全局变量,fn内部一般使用局部变量,而这里是一个全局变量,这是一个潜在的全局变量污染

1 var fn=function(n){2   return n>0 ? n+fn(n-1) : 0;3 }4 console.log('采用传统方式:'+fn(10));

优点:这样就让代码更加简练。又防止了全局变量的污染

1 var fn=(function(n){2   return n>0 ? n+arguments.callee(n-1) : 0;3 })(10);4 console.log('采用callee方式: '+fn);

 

constructor prototype

constructor属性,就是用来构造对象实例的函数引用。

prototype属性,获取对象的原型。

每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。

 contructor,prototype属性是系统自动生成的。但本质上只是是函数对象的属性而已。

对象是一个函数,而函数对象含有contructor,prototype等属性,

那么实例化的过程就是拷贝构造函数属性的过程,所以每个实例自然就拥有了contructor,prototype这两个属性。

 

自定义对象:函数实现的--函数又是Function的一个实例,所以这个自定义对象含有Function对象的一切属性和方法

1 var product = function(){}2 /*自动有一个 prototype属性 它是一个对象--- 原型对象*/3 /* product.prototype也是对象,对象都是函数实现的,这货也包含Function对象的一切属性和方法,所以他也有。*/4 product.prototype.buy=function(){}5 product.prototype={}

 

bind  toString

Bind方法,创建具有与原始函数相同的主体的绑定函数。 在绑定功能中,this对象解析为传入的对象。 该绑定函数具有指定的初始参数。

关于Function.prototype.bind(),我们下次专门去讨论这个它。

好消息是,IE8以下并不支持。

 

toString  返回对象的字符串表示形式。