模拟实现 call apply bind

/**
 * @description 模拟实现 call
 * 1. 改变 this 指向
 * 2. 执行函数
 */
// 用法
var foo = {
    value: 1
}
function bar() {
    console.log(this.foo)
}

bar.call(foo) // 把 bar 的 this 绑定到 foo 上, 只要将bar函数变成foo的属性即可使用foo的this,用完删除

// 变成这样就 OK 啦
var foo = {
    value: 1,
    bar: function() {
        console.log(this.value)
    }
}

/**
 * 模拟实现第一步
 * 1. foo.fn = bar
 * 2. foo.fn()
 * 3. delete foo.fn()
 */
Function.prototype.mycall = function(context) {
    context.fn = this
    context.fn()
    delete context.fn
}

/**
 * 模拟实现第二步
 * call 函数可以传递参数并执行, 参数不确定
 *  var foo = {
        value: 1
    }
    function bar (name, age) {
        console.log(name, age, this.value)
    }
    bar.call(foo, 'agren', 26)
 */
Function.prototype.mycall = function(context) {
    var context = context || window
    context.fn = this
    var args = [...arguments].slice(1) // 拿到第一个到最后一个的参数
    var result = context.fn(...args)
    delete context.fn
    return result
}

/**
 * @description 模拟实现 apply 与 call 类似,只不过,只有两个参数,第二个参数是数组
 */
Function.prototype.myApply = function(context = window) {
    context.fn = this
    var result
    if (arguments[1]) {
        result = context.fn(...arguments[1]) // 还是只取第一个到最后一个的参数
    } else {
        result = context.fn()
    }
    delete context.fn
    return result
}

/**
 * @description 模拟实现 bind 方法 与上面两个类似
 * 1. 设置this 为执行的值,并会返回函数
 * 2. 调用函数时,将给定参数列表,作为原函数参数列表的千若干项
 */
// bind 第一步
Function.prototype.myBind = function(...rest1) {
    const self = this
    const context = rest1.shift() // 拿到第一个参数
    return function(...rest2) {
        return self.apply(context, [...rest1, ...rest2])
    }
}

你可能感兴趣的:(模拟实现 call apply bind)