深入认知----函数

1. 函数的声明方式

函数的声明方式有函数声明语句、函数表达式和Function构造函数三种方式。

  //1.函数的声明语句
  function fn0(){};
  fn0();
  //2.函数表达式:将一个匿名函数赋值给一个新的变量
  var fn1 = function(){};
  var fn2 = function hhh(){};//使用非匿名函数赋值,该函数名hhh相当于函数的形参,只能在函数内部使用
                             //而fn1相当于变量实参,即可在函数内部使用,也可以在外部使用。
  //3.Function构造函数
  var fn2 = new Function('x','y','return x+y');//括号内接收字符串,最后一项为函数体内语句,之前为参数

2. 函数返回值

  • 函数之外使用return会报错;
  • 函数之内不使用return,调用表达式时结果是undefined
  • 若直接==return;==函数直接终止
  • return后的语句不执行,除(try…catch语句)
  • 一个函数可以有多个return语句
  • 如果函数调用时在前面加上了new’前缀,且返回值不是一个对象或者没有返回值,则返回该函数
   
   //返回值不是一个对象
     function fn(){
       return 1;
     }
     var test = new  fn();
     console.log(test)//fn
     //返回值是一个对象
     function fn1(){
       return {a:1};
     }
     var test1 = new  fn();
     console.log(test1)//{a:1}
     

3.函数调用

3.1 函数调用模式
//1.函数调用模式
      function add(x,y){
        console.log(this);//在非严格模式下,window对象
                          //在严格模式下,undefined
        return x+y;
      }
      var sum = add(3,4);
      console.log(sum);
      
      //重写
      function fn(){
        this.a = 1;
        console.log(this);
      }
      fn();
      this.a = 4;//覆盖了之前的1

      //注意:避免全局属性重写带来的问题。
3.2 方法调用模式

   // 2.方法调用模式 
      var obj = {
        //fn称为obj对象的方法
        a : 1,
        fn:function(){
          console.log('111'); // 111
        },
        fn2:function(){
            this.a = 2;// this指向obj
        }
      }
      obj.fn(); // 111
      console.log(obj.a)// 1
      obj.fn2(); 
      console.log(obj.a)// 2
      
3.3 构造调用模式

	 //写法
      function fn0(){
        return 1;
      }
      var obj0 = new fn0;//()可以省略
      console.log(obj0)
      // 传参
      function fn(x){
          this.a = x; 
      }
      var obj = new fn(2); // 指向当前函数
      obj()
      console.log(a)
      
3.4 间接调用模式

var obj = {a:5};
        function sum(x,y){
          return x+y+this.a;
        }
        console.log(sum(1,2)); // NaN,             this->sum
        console.log(sum.call(obj,1,2));// 8        this ->obj
        console.log(sum.apply(obj,[1,2]));// 8     this -> obj

4. 函数参数


    //arguments:实参(类)数组
        function add(x){
            return x+1;
        }
        console.log(add(1)); //2
        console.log(add('1')); //'11'
        console.log(add()); //NaN
        console.log(add(1,2,3)); //2
        //非严格模式下,允许函数出现同名形参,值取最后一个同名参数
        function add1(x,x,x){
          return x;
        }
        console.log(add(1,2,3)); // 3
        //参数个数
        // 实参比形参个数少,剩下的形参都将设置为undefined
        function add2(x,y){
            console.log(x,y);
        }
        add2(1); //NaN
        // 实参比形参多,考虑使用arguments
        function add3(){
          console.log(arguments[0],arguments[1],arguments[2])
        }
        add3(1,2,3);//1 2 3
        

5. 函数重载

重载:定义相同的函数名,传入不同的参数,JS中不存在重载,只能模拟


function add(a){
      return a + 100;
    }
    function add(a,b){
      return a + b + 100
    }
    console.log(add(10)); // NaN
    // 模拟重载
    function add1(){
      if(arguments.length == 0){
        return 100;
      }else if(arguments.length == 1){
        return arguments[0] + 100;
      }else if(arguments.length == 2){
        return arguments[0] + arguments[1] + 100;
      }
    }
    console.log(add()); //100
    console.log(add(10)); //110
    console.log(add(10,1)); //111


6. 参数传递

6.1 基本数据类型

number、string、boolean、NaN、undefined

    //1. 基本数据类型:将参数直接传递给函数
    function add(num){
      num = num +10;
      return num;
    }
    var count = 20;
    var result = add(count);
    console.log(result);
6.2 引用数据类型

Array、Object、Function

    
    //2. 引用参数类型: 会将该参数在内存中的地址复制给局部变量
    function setName(obj){
      obj.name = 'zjn';
      console.log(person.name);// zjn
      obj = new Object();
      obj.name = 'test';
      console.log(obj.name); // zjn
    }
    var person = new Object();
    setName(person);
    console.log(person.name);
    

7. 函数属性

  • length属性

    //arguments对象中的length属性表示实参的个数
    //函数对象中的length属性表示形参的个数

  function add(x,y){
        console.log(arguments.length); // 4
        console.log(add.length) // 2
      }
      add(2,3,4,5)
      
  • name属性

    // 当前函数的名字

function fn(){};
      console.log(fn.name); // fn
      var fn1 = function (){};
      console.log(fn1.name)//  fn1
      var fn2 = function test(){};
      console.log(fn2.name)//  test
      
  • prototype属性

    //每一个函数都有一个prototy属性–是个对象

      function pr(){};
      console.log(pr.prototype);
      fn.prototype.a = 1;
      console.log(fn.prototype); //包括 a:1的对象
      
注:关于原型后面有专门的介绍

8. 函数的方法

//函数的方法继承于父级函数的prototype中,根为构造函数Function();
// 有两个非继承的方法:apply、call

  • apply 和 call 的使用


// aplly({obj},[1,2,3])
      // call({obj},1,2,3)
      window.color = 'red';
      var obj ={
        color: 'blue'
      }
      function sayColor(){
        console.log(this.color);
      }
      sayColor();// red
      sayColor.call(null)//red   严格模式下不可用!!!
      sayColor.call(this);//red
      sayColor.call(window); // red
      sayColor.call(obj); // blue
      sayColor.apply(undefined)//red   严格模式下不可用!!!
      sayColor.apply(this);//red
      sayColor.apply(window); // red
      sayColor.apply(obj); // blue
      
  • apply和call的应用


//1. 找出数组的最大元素
      //正常方式
      var max = Math.max(1,6,5,18,4,8);
      //apply方式
      var arr = [1,6,5,18,4,8]
      var max2 = Math.max.apply(null,arr);
      console.log(max,max2); // 18 18
      //2. 将类数组转化为真数组
      function add(){
        var arr = Array.prototype.slice.apply(arguments)
        console.log(arr); // [1,6,5,4,6,4,8,3,4]
      }
      add(1,6,5,4,6,4,8,3,4)
      //3. 数组追加
      var arr = [];
      Array.prototype.push.apply(arr,[1,2,3,5,4])
      console.log(arr); // [1,2,3,5,4]

      //4. 利用call和apply做继承
      function Animal(name,age){
        this.name = name;
        this.age = age;
        this.sayAge = function(){
          console.log(this.age);
        }
      }
      function Dog(nam,age){
        // 继承Animal
        Animal.call(this,name,age);
      }
      var c = new Dog('大黄',22);  // this -> 实例化 c
      c.sayAge()

      //5. 使用log代理console.log() 

      function log(str){
        console.log.apply(console,arguments)
      }
      var p = '哈哈哈哈'
      log(p)// 哈哈哈哈
  

  • bind()方法


      // bind()方法:es5新增的方法,主要作用--将函数绑定到某个对象中,并且有返回值
      function fnb(y){
        return this.x +y;
      }
      var x =2;
      console.log(fnb(2)) // 4 此时this -> window, x = 2
      var obj = {x:10};
      console.log(fnb.bind(obj)(2)); // bind(obj)将this -> obj, x = 10;

      // 常见的函数式编程 -- 函数柯里化

      function getConfig(color, size, otherOptions){
        console.log(color,size,otherOptions);
      }
      var defaultConfig = getConfig.bind(null,'blue','1024*768');
      defaultConfig('456'); // 'blue',1024*768,456
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值