美文网首页
js中的call,apply,bind详解

js中的call,apply,bind详解

作者: passenger_z | 来源:发表于2020-01-21 20:44 被阅读0次

    function.call(thisArg, arg1, arg2, ...)

    参数
    • thisArg是function运行时this的值

    • arg1,arg2指定的参数列表

    返回值
    • 该function的返回值,如果无返回值则是undefined
    用途
    • 调用父构造函数

      function Product(name, price) {
        this.name = name;
        this.price = price;
      }
      
      function Food(name, price) {
        Product.call(this, name, price);
        this.category = 'food';
      }
      //food
      console.log(new Food('cheese', 5).category);
      //cheese
      console.log(new Food('cheese', 5).name);
      
    • 调用匿名方法

        var btns =             document.getElementsByTagName("button")
           function fun(){
              for(var i =0;i<btns.length;i++){
                 (
                     function (value){
                      btns[value].onclick= function(){
                      console.log(value)
                      }
                     }
                 ).call(this,i)
              }
           }
           fun()
      
    • 改变this指向

      var a = 1;
      var o = {
          a: 2
      }
      
      function b() {
          console.log(this.a);
      }
      
      b(); // 1
      b.call(o); // 2
      
    实现
      Function.prototype.mycall = function(thisArg,...args){
             //this如果为空,指向window
             let context = thisArg===null?window:Object(thisArg)
             let fn =Symbol()
             //避免属性冲突或者被外部修改
             context[fn] = this//获取方法
             let result;
             if(args) {
                result = context[fn](...args);
             } else {
                result = context[fn]();
              }
        
        // 4. 清掉挂载的 fn,并返回
            delete context[fn];
            return result;
         }
    

    func.apply(thisArg, [argsArray])

    apply和call的区别就是接受的参数不一样

    apply接受一个参数数组,call接受参数列表

        Function.prototype.myApply = function(thisArg,args){
             //this如果为空,指向window
             let context = thisArg===null?window:Object(thisArg)
             if (!Array.isArray(args)) {
                throw new TypeError('args is not a Array');
            }
             let fn =Symbol()
             //避免属性冲突或者被外部修改
             context[fn] = this//获取方法
             let result;
             if(args) {
                result = context[fn](...args);
             } else {
                result = context[fn]();
              }
        
        // 4. 清掉挂载的 fn,并返回
            delete context[fn];
            return result;
         }
    

    function.bind(thisArg[, arg1[, arg2[, ...]]])

    参数
    • thisArg

    调用绑定函数时作为 this 参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用 bindsetTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,执行作用域的 this 将被视为新函数的 thisArg

    • arg1,arg2指定的参数列表
    返回值

    function.bind(thisArg[, arg1[, arg2[, ...]]])

    用途

    bind 就是返回一个原函数的拷贝,并拥有指定的 this 值和初始参数,不可以更改箭头函数。

    实现
    Function.prototype.mybind= function(thisArg,...args){
        let context = thisArg===null?window:Object(thisArg)
        let fn = Symbol();  // 避免属性冲突或被外部修改
        let _this = this
        let resultFn = function(...newArgs){
            let resultContext;
            //依据定义如果是new则this指向原构造函数
            if(!new.target){
                resultContext = context
            }else{
                resultContext = this
            }
            resultContext[fn] = _this
            let result = resultContext[fn](...[...args,...newArgs])
            delete resultContext[fn]
            return result;
        }
        //3. 拷贝原函数的 prototype,防止外部修改影响原函数
        if (this.prototype) {
            resultFn.prototype = Object.create(this.prototype);
        }
        return resultFn;
    
    }
    

    相关文章

      网友评论

          本文标题:js中的call,apply,bind详解

          本文链接:https://www.haomeiwen.com/subject/ppgezctx.html