/*
    一.函数在js中扮演了几个角色?
       1.构造函数
       2.普通函数
       3.作为对象function fn(){};  fn.abc=123;
       函数扮演什么角色取决于如何调用
       函数作用:代码的重用
    二.函数的类型及产生方式
       1.内置函数(内置对象/库函数)
       Object/Array/Date/RegExp、String、Number、Boolean、Error、Function
       2.自定义函数
         1.函数声明(匿名函数) //可以先调用后声明
         2.函数表达式 //必须先声明再调用,因为预解析会把var提前,赋值不会提前
         3.new Function()
         // 如下的代码不可以使用(在某些浏览器两步都走)
         // if(flag){
         //     function a(){
         //         console.log(‘a‘);
         //     }
         // }else{
         //     function b(){
         //         console.log(‘b‘);
         //     }
         // }
        --------------------------
         new Function();
         var foo=new Function(‘param‘,‘console.log(param)‘)
         f00(1);
         // new Function() 产生一个函数
         // 如果函数没有参数,那么Function的参数表示函数体
         // 如果函数有参数,那么Function最后一个参数表示函数体,之前的表示实际参数
         产生函数的缺点:代码的可读性较低;性能比较低(有一个字符串转成js代码的过程比较耗时)
         // new Function()的优点:可以动态解析js字符串形式的代码
    三.函数的调用方式
       1.普通函数调用
       2.构造函数实例化
       3.对象方法调用
       4.call和apply
       5.自调用
     */
       // 4.call和apply的作用 // call的参数是单个的;apply的参数是数组
       //   a.可以调用函数
       //   b.改变函数内部this的指向
       //   c.借用其他对象的方法
       //   d.把类数组转成数组
         // function fn(a,b){
         //    console.log(a+b);
         // };
         // //第一个参数是null代表指向不发生改变,只是占位置,第一个参数必须传
         // fn.call(null,1,2);
         // fn.apply(null,[1,2]);
 //四.类数组及其转化
      // 1.类数组是一个对象;对象的键是整数形式的索引,与数组的键类似;必须有length属性,length属性的值与索引形式的键值对个数相同;注意类数组不是数组,不可以调用数组的方法。
         // var obj = {0:‘hello‘,1:‘ni‘,2:‘nihao‘,length:3};
         // //转化成数组
         // //var arr=[].splice.call(obj,0);
         // var array=Array.prototype.slice.apply(obj,[0]);
         // console.log(arr);
         // length的作用,如果改为几转成数组就存在几个
        //var obj = {0:‘hello‘,1:‘ni‘,2:‘nihao‘,length:2};
        //var arr=[].splice.call(obj,0);
        //console.log(arr);
        //console.log(obj)
      //2.bind本身不会调用函数,仅仅会改变函数内部的this指向,并且返回一个新的函数(新函数唯一的变化就是this变了,变成了bind的第一个参数)
     //     function foo(c,d) {
     //    console.log(this.a + this.b + c + d);
     //  }
     //   foo();
     //   var fn = foo.bind({
     //     a : 3,
     //     b : 4
     // },1,2);
     // fn();
     // --------------------------------------
     //    var obj = {
     //     a : 1,
     //     b : 2
     // }
     // setTimeout((function(){
     //     // console.log(this == obj);
     //     console.log(this.a + this.b);
     // }).bind(obj),1000);
     //3.关于agruments
     // 类数组场景arguments
     //  function foo(a,b){
     //     // 函数名称.length表示形参的个数
     //    console.log(foo.length);
     //    // arguments包括所有的实参,arguments本质上是类数组
     //    // console.dir(arguments);
     //    var ret = [].slice.call(arguments);
     //    ret.push(5);
     //    console.log(ret);
     //    // arguments的length表示实参的个数
     //    console.log(arguments.length);
     // }
     // foo(1,2,3,4);
 // 五.高阶函数
    // 1、作为参数的函数
// 2、作为返回值的函数
原文:http://www.cnblogs.com/woniubushinide/p/6822574.html