zoukankan      html  css  js  c++  java
  • 手动实现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);
  • 相关阅读:
    datetime模块
    python正则表达式练习题
    Python入门——turtle库的使用
    Python入门——Python程序语法元素
    Python入门——eval() 函数
    Python入门——实例1_温度转换
    Python入门——编程方式
    Python入门——程序的基本编写方法
    Python入门——编译和解释
    SQL中isnull、ifnull和nullif函数用法
  • 原文地址:https://www.cnblogs.com/cazj/p/14304078.html
Copyright © 2011-2022 走看看