zoukankan      html  css  js  c++  java
  • 《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));//同上
      }

     

      

      

      

  • 相关阅读:
    【ACM非算法部分】综合篇
    【解题报告】CF Round #320 (Div. 2)
    【解题报告】13级个人结业赛(二) ——动(dou)态(bu)规(hui)划(zuo)专场
    【解题报告】13级个人结业赛(一) ——涨姿势专场
    【解题报告】三校联盟专场一
    【解题报告】编程之美复赛 ——猜数字
    【解题报告】Codeforces Round #301 (Div. 2) 之ABCD
    【解题报告】编程之美初赛二 扑克牌
    【通知】
    【test】
  • 原文地址:https://www.cnblogs.com/angelgril/p/3819911.html
Copyright © 2011-2022 走看看