• 实现new、apply、call、bind


    new方法

    • 创建一个新对象且将其隐式原型__proto__指向构造函数原型
    • 执行构造函数修改this指向
    • 返回该对象
    function myNew(fun){
        return (...args)=>{
            let obj = {
                __proto__:fun.prototype
            };
            fun.call(obj,...args);
            return obj; 
        }
    }
    

    apply

    • 将要修改this方法的函数绑定到传入的对象上并且执行绑定的函数 、

    核心内容

    // 为了让所有函数都有该方法,所以需要绑定到Function的原型上
    Function.prototype.myApply = function(context){
        context.fn = this; // 为了让函数中的this指向传入的对象,需要让对象来调用该方法
        context.fn(...arguments[1])
        return res;   
    }
    

    完整实现

    Function.prototype.myApply = function(context){
        // 判断调用者是否为函数
        if(typeof this !=='function'){
            throw new TypeError('not function')
        }
    
        context = context || window;
        context.fn = this; // 为了让函数中的this指向传入的对象,需要让对象来调用该方法
        let res = null;
        if(arguments[1]){
            res = context.fn(...arguments[1])
        }else{
            res = context.fn();
        }
        //  删除绑定
        delete context.fn;
        return res;   
    }
    

    call

    • 与apply的区别就是传参的方式不一样,apply第二个参数是数组,call方法是一个个的传递

    核心内容

    // 将方法挂载到目标上执行并返回
    Function.prototype.mycall = function(context){
        console.log(arguments); // {0:{name:bonly},1:1,2:2}
        console.log(...arguments); // { name: 'bonly' } 1 2 3
        console.log([...arguments].slice(1)); // [1,2,3]
        let args = [...arguments].slice(1);
        context.fn = this;
        context.fn(...args);
    }
    

    完整版

    // 思路:将要改变this指向的方法挂到目标this上执行并返回
    Function.prototype.mycall = function (context) {
      if (typeof this !== 'function') {
        throw new TypeError('not funciton')
      }
      context = context || window
      context.fn = this
      let arg = [...arguments].slice(1)
      let result = context.fn(...arg)
      delete context.fn
      return result
    } 
    
    

    bind

    • 与call和apply的不同就是只是修改this指向,并且返回函数等待执行

    核心内容

    Function.prototype.myBind = function(context){
        context.fn = this;
        return () => {
            let args = [...arguments].slice(1);
            context.fn(...args);
        }
    }
    

    完整版

    // 思路:类似call,但返回的是函数
    Function.prototype.mybind = function (context) {
      if (typeof this !== 'function') {
        throw new TypeError('Error')
      }
      let _this = this
      let arg = [...arguments].slice(1)
      return function F() {
        // 处理函数使用new的情况
        if (this instanceof F) {
          return new _this(...arg, ...arguments)
        } else {
          return _this.apply(context, arg.concat(...arguments))
        }
      }
    }
    
    
  • 相关阅读:
    Spring Boot启动时执行初始化操作三种方法分享
    springboot自定义验证传值范围
    动态数据源玩起来
    多线程之Semaphore登录限流示例
    elementui表格自定义格式实现原理???
    31 Days of Windows Phone | Day #5 System Theming
    SQL 子查询关联查询和非关联查询 性能分享
    windows phone app 发布后在市场里找不到呢。
    APP Hub 应用发布失败,请问大家都是怎么设置可以成功提交哦
    WPF:Main方法到哪里去了?
  • 原文地址:https://www.cnblogs.com/bonly-ge/p/12067251.html
Copyright © 2020-2023  润新知