zoukankan      html  css  js  c++  java
  • 实现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))
        }
      }
    }
    
    
  • 相关阅读:
    码农提高工作效率 (转)
    Python快速教程 尾声
    C#基础——谈谈.NET异步编程的演变史
    [C#]動態叫用Web Service
    零极限 核心中的核心和详解
    项目经理应该把30%的时间用在编程上
    高效能程序员的七个习惯
    我们如何进行代码审查
    工作经常使用的SQL整理,实战篇(二)
    C# Socket网络编程精华篇 (转)
  • 原文地址:https://www.cnblogs.com/bonly-ge/p/12067251.html
Copyright © 2011-2022 走看看