• js-call aplly bind2


    call apply bind

    1. 介绍:

      1. 是Function对象原型链上的方法,主要作用是改变函数执行时的上下文(改变this指向),将对象B的方法交给对象A来执行,并且是立即执行的。
      2. 那为什么要改变函数的this指向,举个生活中例子你就明白了,比如你(对象A)上班时候想点根烟抽(事件),但是你没有打火机(方法),这时候你又不想偷跑出去买,所以你向你同事(对象B)借给一个打火机(方法),来点根烟抽(事件)。
      3. 在程序中也是一样,对象A有一个方法a,而 B 对象因为某种原因,也要用到方法a,那么是再为对象B添加方法a呢,还是借用一下 对象A的方法a呢?当然是借用对象A的,这样既完成了需求,又减少了内存的占用。
    2. call、apply、bind的作用是改变函数运行时this的指向

    3. 相同点:

      1. 调用的对象必须是Function对象;

      2. 第一个参数是一个对象。调用者的this会指向这个对象。如果不传,则默认为全局对象 window。或者当第一个参数为null、undefined的时候,默认指向window。

      3. var age = '17';
        var name = '小明'
        let A = {
            setInfo(){
                console.log('我' + this.name + '今年' + this.age + '岁')
            }
        }
        let B={
            age:37,
            name:'老王'
        }
        A.setInfo();//我undefined今年undefined岁
        A.setInfo.call();//我小明今年17岁
        A.setInfo.apply();//我小明今年17岁
        A.setInfo.bind()();//我小明今年17岁
        A.setInfo.call(B);//我老王今年37岁
        A.setInfo.apply(B);//我老王今年37岁
        A.setInfo.bind(B)();//我老王今年37岁
        
    4. 不同点:

      1. 第二个参数不同,call和bind接收一个参数列表,但apply不一样,接收一个包含多个参数的数组;

      2. 执行返回不同,call和apply返回的是调用对象执行后的值,bind返回的是函数需要再次调用。

      3. let A = {
            setInfo(province,city){
                console.log('我' + this.name + '今年' + this.age + '岁,来自'+province+'省'+city+'市')
            }
        }
        let B={
            age:37,
            name:'老王'
        }
        A.setInfo.call(B,'四川','成都');//我老王今年37岁,来自四川省成都市
        A.setInfo.apply(B,['四川','成都']);//我老王今年37岁,来自四川省成都市
        A.setInfo.bind(B,'四川','成都')();//我老王今年37岁,来自四川省成都市
        
        
        
    5. 应用场景

      1. 求数组中的最大和最小值

        var arr = [1,2,3,89,46]
        var max = Math.max.apply(null,arr)//89
        var min = Math.min.apply(null,arr)//1
        
      2. 将类数组转化为数组

        var trueArr = Array.prototype.slice.call(arrayLike)
        
      3. 数组追加

        var arr1 = [1,2,3];
        var arr2 = [4,5,6];
        var total = [].push.apply(arr1, arr2);//6
        // arr1 [1, 2, 3, 4, 5, 6]
        // arr2 [4,5,6]
        
      4. 判断变量类型

        function isArray(obj){
            return Object.prototype.toString.call(obj) == '[object Array]';
        }
        isArray([]) // true
        isArray('dot') // false
        
      5. 调用父构造函数实现继承

          function Personal(name,age){
                this.name=name;
                this.age=age;
                this.setInfo=function(){
                    console.log('我' + this.name + '今年' + this.age + '岁')
                }
            }
            const A=new Personal('小明','12');
            function FromTo(name,age,province,city){
                Personal.call(this, name,age)
                this.province=province;
                this.city=city;
                this.setAddress=function(){
                	console.log('我' + this.name + '今年' + this.age + '岁,来自'+province+'省'+city+'市')
                }
            }
            const B=new FromTo('老王','37','四川','成都');
            A.setInfo();//我小明今年12岁
            B.setInfo();//我老王今年37岁
            B.setAddress();//我老王今年37岁,来自四川省成都市
        
    6. 封装一个修改 this 指向的方法

      function bindThis(f, oTarget,...rest) {
          const param=Array.from(arguments)[2];
          if(param && Array.isArray(param)){
              return function() {
                  return f.apply(oTarget,...rest);
              };
          } else if(f.bind){
              return f.bind(oTarget,...rest)
          }else{
              return function() {
                  return f.call(oTarget,...rest);
              };
          }
      }
      bindThis(A.setInfo,B, ['四川', '成都'])();//我老王今年37岁,来自四川省成都市
      bindThis(A.setInfo,B, '四川', '成都')();//我老王今年37岁,来自四川省成都市
      
      
  • 相关阅读:
    1041 考试座位号
    1040 有几个PAT
    1039 到底买不买
    1038 统计同成绩学生
    1037 在霍格沃茨找零钱
    1036 跟奥巴马一起编程
    1035 插入与归并
    vue-router--路由传参
    vue-router--路由原理
    vuex--在computed中使用
  • 原文地址:https://www.cnblogs.com/ycyc123/p/14823903.html
Copyright © 2020-2023  润新知