《javascript语言精粹》——第4章函数

  函数就是对象

【1】、函数字面量即(函数表达式)包括四部分:

  第一部分:保留字function;

  第二部分:函数名称,可有可无;

  第三部分:包围在一对小括号的一组参数,参数用逗号隔开;

  第四部分:包围在一对花括号的一组语句,是函数的主体;

函数字面量可以出现在任何允许表达式出现的地方。

【2】、调用有四种调用模式:

  除了声明时定义的形参,每个函数接收附加的的参数:this和arguments  ,this的值取决于调用的模式.

  第一种:方法调用模式:

    var aa={
      value:0,
      increment:function(inc){
        this.value+=typeof inc ==='number'?inc:1;  //面向对象编程,方法里面就可以直接调用对象中的属性
      }
    };
    aa.increment();
    document.writeln(aa.value);//1
    aa.increment(2);
    document.writeln(aa.value);//3

  第二种:函数调用模式:

  function add(a,b)
  {
  return a+b;
  }

    aa.double1=function(){

      var that=this; //把this赋值给一个变量

      var hepler=function(){

        that.value=add(that.value,that.value);

      };

      hepler();//以函数的形式调用helper

    };

    aa.double1();

    document.writhln(aa.value);  //aa.value,value在第一种方法中已经写了。结果为6,因为在第一种方法中,已经给value赋了值3,所以,3+3=6

  第三种:构造器调用模式:

    var Quo=function(string){
      this.status=string;
    };
    Quo.prototype.get_status=function(){
      return this.status;
    };
    var myquo=new Quo("confused");
    document.write(myquo.get_status()); //confused

  第四种:Apply调用模式:

    apply()接收两个参数:第一个是将被绑定给this的值,第二个就是一个参数数组

    var array=[3,4];
    var sum=add.apply(null,array); //add是前面的第二种模式里面的add()
    alert(sum);

    var statusObject={
      status:'OK'
    };
    var status=Quo.prototype.get_status.apply(statusObject);//上面get_status第三种模式里面创建了
    document.write(status);//OK

 【3】、参数--arguments类似于数字,但不是数组

    var sum=function(){
    var i,sum=0;
      for(i=0;i<arguments.length;i++){
        sum+=arguments[i];
      }
      return sum;
    };
    document.write("<br/>"+sum(1,2,3,4,5));//可以添加任意数量的参数

【4】、返回--return语句

  调用函数前面加上new前缀方式,且返回的结果不是一个对象类型,那么返回的就是这个对象的新对象

【5】、异常

  var add=function(a,b){
    if(typeof a!=='number'||typeof b!=='number'){
      throw{   //该异常类型中的属性可以自定义
          name:"TypeError",
          message:"add needs number",
          notice:"请注意看清楚类型"
      };
    }
    return a+b;
  };

  var try_it=function(){
    try{
      add("seven");
    }
    catch(d){
      document.write(d.name+":"+d.message+"<br/>"+d.notice);
    }
  };
  try_it();

【6】、给类型增加方法

  Function.prototype.method=function(name,func){

    if(!this.prototype[name]){

      this.prototype[name]=func;

    }
    return this;
  };
  Number.method('integer',function(){
    return Math[this<0?'ceil':'floor'](this); //哈哈,我闹了一个笑话,就是总觉得是-4不是-3,-4<-3呀!别被带进去了
  });

  document.write((10/3).integer()); 
  String.method('trim',function(){
    return this.replace(/^\s+|\s+$/g,'');
    /** /^\s+|\s+$/g 的解释就是:\s: space, 空格
    +: 一个或多个
    ^: 开始,^\s,以空格开始
    $: 结束,\s$,以空格结束
    |:或者
    /g:global, 全局
    **/

  });
  document.write("<br/>"+'"'+" neat ".trim()+'"');

【7】、递归

  var fat=function fac(i,a){
    a=a||1;//这句代码的意思就是当a不存在的时候,取值1,也就是a=a?a:1
    if(i<2)
    {
      return a;
    }
    return fac(i-1,a*i); //a*i的过程==>    1*4-->4*3-->12*2
  };
  document.write("<br/>"+fac(4));//24

【8】、作用域--缺少块级作用域,所以最好是在函数体的顶部把要的变量全部声明好

  var foo=function(){
  var a=3,b=5;
    var bar=function(){
      var b=7,c=11;
      //此处,a=3,b=7,c=11
      a+=b+c;
      //此处,a=21,b=7,c=11
    };
    //此处,a=3,b=5,c为定义
    bar();
    //此处,a=21,b=5,c未定义
    document.write("<br/>a:"+a+"<br/>b:"+b+"<br/>");
  };
  foo();

【9】、闭包

  示例1:

  //设置一个DOM节点的为黄色,然后把它渐变为白色,使得背景颜色渐变
  var fade=function(node){
  var level=1;
  var step=function(){
    var hex=level.toString(16);
    node.style.backgroundColor='#FFFF'+hex+hex;
    if(level<15)
    {
      level+=1;
      setTimeout(step,500);
    }
  }
    setTimeout(step,500);
  }
  fade(document.body);

  示例2:
  var add_the_handle=function(nodes){
    var i;
    for(i=0;i<nodes.length;i++){
      nodes[i].click=function(i){
        return function(e){
          alert(e);
        };
        alert(nodes[i]);
      }(i);
    }
  };

【10】、模块

  示例1:

  String.method('deentityfiy',function(){
  var entity={
    quot:'""',
    lt:'<',
    gt:'>'
    };

    return function(){
      return this.replace(/&([^&;]+);/g,
        function(a,b){
        var r=entity[a];
        return typeof r==='string'?r:a;
      });
    };
  }());

  document.write("<br/>"+'&lt;&gt;&quot'.deentityfiy());

  示例2:生成唯一的序列号

  var serial_maker=function(){
  var prefix='';
  var seq=0;
  return{
    set_prefix:function(p){
      prefix=String(p);
    },
    set_seq:function(s){
      seq=s;
    },
    gensym:function(){
      var result=prefix+seq;
      seq+=1;
      return result;
    }
  };
  };

  var seqer=serial_maker();
  seqer.set_prefix("Q");
  seqer.set_seq(1000);
  document.write("<br/>"+seqer.gensym());

 【11】、级联

  注意:启用了级联的Ajax类库,才会允许以下的编码形式

  getElement('myBoxDiv') //id为myBoxDiv的DOM元素
  .move(350,150)
  .width(100)
  .height(100)
  .color('green')
  .border('10px outset')
  .padding('4px')
  .appendText('Please stand by')
  .on('mousedown',function(m){
  this.startDrag(m,this.getNinth(m));
  })
  .on('mousemove','drag')
  .on('mouseup','stopDrag')
  .later(2000,function(){
  this.color('yellow')
  .setHTML('你有病吧?')
  .slide(400,40,200,200);
  })
  .tip('This box is resizeable');

【12】、套用--将一个函数和传递给它的参数相结合产生一个新的函数

  Function.method('curry',function(){
    var sli=Array.prototype.slice,
    arg=sli.apply(arguments), //使的arg拥有sli的slice中的concat方法
    that=this;
    return function(){
      return that.apply(null,arg.concat(sli.apply(arguments)));
    };
  });
  var add1=add.curry(1);//这里就是套用,add是之前写的一个两两相加的函数
  document.write("<br/>"+add1(6));//7

【13】、记忆

  var ss=function(n){
    return n<2?n:ss(n-1)+ss(n-2);
  };

  for(var i=0;i<=10;i++){
    //document.write("<br/>"+i+":"+ss(i));同下
  }

  var aa=function(){
    var demo=[0,1];
    var fab=function(n){
      var result=demo[n];
      if(typeof result!=='number'){
        result=fab(n-1)+fab(n-2);
        demo[n]=result;
      }
      return result;
    };
    return fab;
  }();

  for(var i=0;i<=10;i++){
    //document.write("<br/>"+i+":"+aa(i));

 结果是:0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:13
8:21
9:34
10:55
  }

  var memoizer=function(memo,fundamental){
    var shell=function(n){
      var result=memo[n];
      if(typeof result!=="number"){
        result=fundamental(shell,n);
        memo[n]=result;
      }
      return result;
    };
    return shell;
  };

  var fibonacci=memoizer([0,1],function(shell,n){
    return shell(n-1)+shell(n-2);
  });
  for(var j=0;j<=10;j++){
    document.write("<br/>"+j+":"+fibonacci(j));//同上
  }

 

 

 

 

 

 

 

 

 

 

 

 

  

  

  

posted on 2014-07-02 12:09  福气满满好运连连  阅读(266)  评论(0编辑  收藏  举报