• 手动实现call、apply和bind


    如果没有传参,那么this默认指向的window 

    let a = {
        value: 1
    }
    
    function parent(sex, weight) {
        this.name = '1'
        this.age = 12
        this.sex = sex ? sex : null
        this.weight = weight ? weight : null
        console.log(123)
    }

    call的实现   call接受参数的方式  call(obj, params1, params2, ....)

    Function.prototype.myCall = function (context) {
        let currentObj = context ? context : window // 这里就是传入的第一个参数
        currentObj.fn = this // 将parent函数存起来,parent调用的myCall,此时this指向的就是该方法
        let arg = [...arguments].slice(1) // 将参数中除了第一个之后的全部存起来,第一个就是上下文要用的这个对象
        console.log(...arg)
        currentObj.fn(...arg) // 将参数传入,此时调用fn的是currentObj 即为传入的对象a,所以parent中的this会指向a
        delete context.fn // 将函数删除
    }
    // 测试代码
    // parent.myCall(a, 'mingzi', 'nianling')
    // console.log(a);

    apply的实现  apply接受参数的方式  call(obj, [params1, params2, ....])

    Function.prototype.myApply = function (context) {
        let currentObj = context ? context : window // 这里就是传入的第一个参数
        currentObj.fn = this // 将parent函数存起来,parent调用的myCall,此时this指向的就是该方法
        console.log(arguments) // [{value: 1}, ['张三', '12']]
        if(arguments[1]) {
            currentObj.fn(...arguments[1])
        } else {
            currentObj.fn()
        }
        delete currentObj.fn
    }
    // 测试代码
    // parent.myApply(a, ['boy', '50'])
    // console.log(a)

     bind()实现  

    // 实现bind()方法 调用bind()必须是一个函数   可以通过new修改this  new的优先级最高 bind()可以将参数分两次传递进来
    Function.prototype.myBind = function (context) {
        if(typeof this !== "function") { // 如果不是函数则直接抛出
            throw new TypeError('Error')
        }
        let self = this // 保存this,即为parent
        let arg = [...arguments].slice(1) // 将参数中除了第一个之后的全部存起来
        // bind()返回的是一个函数,所以可以使用new,并且会修改this的指向
        return function F() {
            if(this instanceof F) { // 如果new执行此时即为true
                return new self(...arg, ...arguments) // 返回new parent(第一次传递的参数, 第二次传递的参数) =》  arguments是执行返回的函数时的参数
            }
            return self.apply(context, [...arg, ...arguments]) // 如果没有执行new  那么直接执行parent,通过apply会将this执行最初传进来的对象a
        }
    }
    
    // 测试代码
    
    let bindResult = parent.myBind(a, 'women')
    let result = new bindResult('666')
    console.log(result);
  • 相关阅读:
    MySQL优化—工欲善其事,必先利其器(2)
    MySQL优化—工欲善其事,必先利其器之EXPLAIN
    Linux工具安装和常用配置
    .Net Core配置文件介绍
    Centos7上开发.Net Core项目
    VMWare的host-only/bridged/NAT连接图文介绍
    Quartz.net 3.x使用总结(二)——Db持久化和集群
    Vuex实现状态管理
    Quartz.net 3.x使用总结(一)——简单使用
    C#获取根目录的方法总结
  • 原文地址:https://www.cnblogs.com/cazj/p/14304078.html
Copyright © 2020-2023  润新知