函数就是对象

【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));//同上
  }

 

  

  

  

《javascript语言精粹》——第4章函数的更多相关文章

  1. 《JavaScript语言精粹》第二章-语法 简单笔记

    注释 JavaScript提供两种注释: /* */包围的块注释及//开头的行注释. 注释应该被优先用来提高程序的可读性,注释要精确地描述代码,没有用的注释比没有注释更糟糕. /* */块注释对于被注 ...

  2. 你想了解的《javaScript语言精粹》(三)

    # javaScript语言精粹  # 第三章 对象 - javaScript 数据类型     1. 基础数据类型         Number String Boolean Undefined N ...

  3. 《JavaScript语言精粹》之函数化

    写在前面 看到好多书评和读书笔记都说<JavaScript语言精粹>字字珠玑,名不虚传..当然,要看得懂才行 其实个人认为函数化部分不是很好,举的例子不是十分恰当,之前看不懂是因为被成功误 ...

  4. JavaScript中对象与函数的某些事[JavaScript语言精粹-N1]

    今天在读<JavaScript语言精粹>的时候,关于函数的一个部分,始终觉得有点难以理解,代码如下: 1: var obj = (function(){ 2: var value = 0; ...

  5. JavaScript语言精粹 笔记02 函数

    函数函数对象函数字面量调用参数返回异常给类型增加方法递归作用域闭包回调模块级联套用记忆   函数 1 函数对象 在JS中函数就是对象.对象是“名/值”对的集合并拥有一个连接到原型对象的隐藏连接.对象字 ...

  6. 《JavaScript语言精粹》【PDF】下载

    <JavaScript语言精粹>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382204 内容简介 javascript曾是&q ...

  7. JavaScript 语言精粹笔记3

    方法 毒瘤 糟粕 记录一下阅读蝴蝶书的笔记,本篇为书中最后一部分:方法.代码风格.优美的特性.毒瘤.糟粕等. 方法 这一章主要介绍了一些方法集.这里写几个我不太熟悉的方法和要点吧. array.joi ...

  8. 《JavaScript语言精粹》小记

    一.前言 以下内容均摘自<JavaScript语言精粹>一书,本人在读这本书时,发现作者诠释JavaScript很犀利,特别是数组部分,固记录下来,想和大家分享下. 随笔主要包含两大部分: ...

  9. javascript语言精粹

    内容选自:<javascript语言精粹> 1.6种值会为假(==false),分别是false,null,undefined,' ',0,NaN 2.typeof有6种值,分别是'num ...

  10. Javascript 语言精粹 代码片段合集

    Javascript 语言精粹 代码片段合集 标签:Douglas-Crockford Javascript 最佳实践 原文链接 更好的阅读体验 使用一个method 方法定义新方法 Function ...

随机推荐

  1. push以及pop,shift,unshift

    压入数组:往数组后面加:push         arr.push()返回值为添加后数组的长度 往数组前面加:unshift     arr.unshift()返回值为添加后数组的长度 拿出数组:拿掉 ...

  2. GUI矩形、椭圆、线、框架

    所有的Swing组件必须由时间调度线程(event dispatch thread)进行配置,线程将鼠标点击和键盘敲击控制转移到用户接口组件.下面的代码片段是事件调度线程中的执行代码: EventQu ...

  3. Java 向Hbase表插入数据报(org.apache.hadoop.hbase.client.HTablePool$PooledHTable cannot be cast to org.apac

    org.apache.hadoop.hbase.client.HTablePool$PooledHTable cannot be cast to org.apac 代码: //1.create HTa ...

  4. JavaScript的异步机制

    我们经常说JS是单线程的,比如node.js研讨会上大家都说JS的特色之一是单线程的,这样使JS更简单明了,可是大家真的理解所谓JS的单线程机制吗?单线程时,基于事件的异步机制又该当如何 1 先看下两 ...

  5. elasticearch 安装

    1.elasticsearch需要安装jdk1.7以上 2.在ubuntu下不能以root运行,需要建立专门账号 添加组 root@ubuntu:~/Downloads/elasticsearch-/ ...

  6. 优化viewHolder

  7. Day05_JAVAEE系列:XML

    XML概述 1)什么是xml? xml, eXtend Markup Language, 可扩展标记语言 2) html vs xml 都由w3c组织制定的. html语法特征:语法比较松散      ...

  8. 转:创建编码的WebTest

    创建编码的WebTest•通常,通过将现有的已记录Web测试转换为编码的Web测试来创建编码的Web测试.记录的Web测试以“Web测试编辑器”中可见的请求树开头.编码的Web测试是一个生成一系列We ...

  9. Base64编码Java实现

    一.什么是Base64编码 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一.Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输. 由于一些二进制字符在 ...

  10. Restful based service 的跨域调用

    1.关于跨域, w3c的官方文档:https://www.w3.org/TR/cors/ 2.有时间再整理吧. <html> <head> <script src=&qu ...