JavaScript的函数的进阶部分|集创考核第八篇笔记

74 阅读4分钟

函数进阶

  • 函数的定义和调用

    • 函数的定义方式

      • 函数声明方式function关键字(命名函数)

        function fn() {};
        
      • 函数表达式(匿名函数)

        var fun = function() {};
        
      • new Function('参数1','参数2','函数体');

        var f = new Function('a','b','console.log(a + b)');
        f(1,2);      //输出3
        
        • Function里面参数都必须是字符串格式

        • 第三种方式执行效率低,也不方便书写,因此较少使用

        • 所有函数都是Function的实例(对象)

        • 函数也属于对象

        • QQ图片20220222155749

    • 函数的调用方式

      • 普通函数

        function fn() {
            console.log('kk');
        }
        fn();
        fn.call();
        
      • 对象的方法

        var o = {
            sayHi:function() {
                console.log('kk');
            }
        }
        o.sayHi();
        
      • 构造函数

        function Star() {
            
        }
        new Star();
        
      • 绑定事件函数

        btn.onclick = function( ) {};         //点击按钮调用
        
      • 定时器函数

        setInterval(function() {},1000);            //这个函数是定时器自动一秒钟调用一次
        
      • 立即执行函数

        (function() {
            console.log('ok')
        })()                //立即执行函数是自动调用
        
  • this

    • 这些this的指向,是我们调用函数的时候确定的。调用方式的不同决定了this的指向不同。一般指向我们的调用者

    • 调用方式this指向
      普通函数调用window
      构造函数调用实例对象,原型对象里面的方法也指向实例对象
      对象方法调用该方法所属对象
      事件绑定方法绑定事件对象
      定时器函数window
      立即执行函数window
    • 改变函数内部this指向

      JavaScript为我们专门提供了一些函数方法来帮我们更优雅的处理函数内部this的指向问题,常用的有bind()、call()、apply()三种方法

      • call方法

        • call()方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的this指向

        • tun.call(thisArg,arg1,arg2,……)
          
          例子:
          function fn(a,b) {
            console.log(this);
              console.log(a + b);
          }
          fn.call();             //指向window
          fn.call(o,1,2);              //指向o,输出o对象和3
          
        • call第一个可以调用函数,第二个可以改变函数内的this指向

        • call的主要作用可以实现继承

          function Father (uname,age,sex) {
              this.uname = uname;
              this.age = age;
              this.sex = sex;
          }
          function Son () {
              Father.call(this,uname,age,sex);
          }
          var son = new Son('刘德华',18,'男');
          
      • apply方法

        • apply()方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的this指向

        • fun.apply(thisArg,[argsArray])
          
          例子:
          var o = {
              name:'andy'
          };
          function fn() {
              console.log(this);
          }
          fn.apply(o);               //此时指向o
          
        • thisArg:在fun函数运行时指定的this值

        • argsArray:传递的值,必须包含在数组里面

        • 返回值就是函数的返回值,因为他就是调用函数

        • apply第一个可以调用函数,第二个可以改变函数内的this指向,但是它的参数必须是数组(伪数组)

        • apply的主要应用,比如我们可以利用apply借助于数学内置对象求最大值

        var arr = [1,66,3,99,4];
        var max = Math.max.apply(Math,arr);           //不需要改变this指向的时候,第一个参数可以写null或原对象
        console.log(max);              //输出99
        
      • bind方法(bind——绑定,捆绑的意思)

        • bind()方法不会调用函数,但是能改变函数内部this指向

        • fun.bind(thisArg,arg1,arg2,……)
          
          例子:
          var o = {
              name:'andy'
          };
          function fn() {
              console.log(this);
          }
          
          var f = fn.bind(o);            //只绑定不调用,因此没有输出,返回原函数拷贝,所以用另一个值接收它
          f();                        //输出o对象
          
        • thisArg:在fun函数运行时指定的this值

        • arg1,arg2:传递的其他参数

        • 返回由指定的this值和初始化参数改造的原函数拷贝(即原函数改变this之后产生的新函数)

        • 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向,此时用bind

        • 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮

          <button>
              按钮
          </button>
          
          <script>
          var btn = document.querySelector('button');
          btn.onclick = function() {
              this.disabled = true;                //这个this指向btn按钮
              setTimeout(function() {
                 // this.disabled = false;          //定时器函数里面的this指向window
                  this.disabled = false;
              }.bind(this),3000)                   //给定时器函数绑定bind,使其this指向btn,因为bind在定时器函数外面,在onclick函数里面,所以bind中的this指向的是btn按钮
          }
          </script>
          
        • 有多个按钮时

          <button>
              按钮
          </button>
          <button>
              按钮
          </button>
          <button>
              按钮
          </button>
          
          <script>
          var btns = document.querySelectorAll('button');
              for(var i = 0;i < btns.length;i++) {
                  btns[i].onclick = function() {
                      this.disabled = true;                //这个this指向btn按钮
                      setTimeout(function() {
                      // this.disabled = false;          //定时器函数里面的this指向window
                      this.disabled = false;
                   }.bind(this),3000)                   //给定时器函数绑定bind,使其this指向btn,因为bind在定时器函数外面,在onclick函数里面,所以bind中的this指向的是btn按钮
          }
              }
          
          </script>
          
      • call、apply、bind总结

        • 相同点:都可以改变函数内部的this指向

        • 区别点:

          • call和apply会调用函数,并且改变函数内部this指向
          • call和apply传递的参数不一样,call传递参数arg1,arg2形式,apply必须数组形式[arg]
          • bind不会调用函数,可以改变函数内部this指向
        • 主要应用场景:

          • call经常做继承

          • apply经常跟数组有关系,比如借助于数学对象实现数组最大值最小值

          • bind不调用函数,但是还想改变this指向,比如改变定时器内部的this指向