简单手写如何改变this的指向

120 阅读1分钟

改变this的指向

// 实现call函数
Function.prototype.myCall = function(context) {
    // 1、判断调用对象是否为函数
    if (typeof this !== 'function') {
        throw TypeError('typeof error')
    }
    // 2、 获取参数
    let args = [...arguments].slice(1),
        result = null
        // 3、判断context是否传入,否则设置为window
    context = context || window
        // 4、将调用对象设为对象函数
    context.fn = this
        // 5、调用函数
    result = context.fn(...args)
        // 6 将属性删除
    delete context.fn
        // 7、返回
    return result
}

// 实现apply函数
Function.prototype.myApply = function(context) {
    // 1、判断调用对象是否为函数
    if (typeof this !== 'function') {
        throw TypeError('type error')
    }
    // 2、判断context是否传入,否则设置为window
    context = context || window
        // 3、将调用对象设为对象函数
    context.fn = this
        // 4、调用函数
    if ([...arguments][1]) {
        result = context.fn([...arguments][1])
    } else {
        result = context.fn()
    }
    // 5、 将属性删
    delete context.fn
        // 6、返回
    return result
}

// 实现 bind函数
Function.prototype.myBind = function(context) {
    // 1、判断调用对象是否为函数
    if (typeof this !== 'function') {
        throw TypeError('type error')
    }
    // 2、获取参数
    let args = [...arguments].slice(1),
        fn = this

    return function Fn() {
        // 根据调用方式,传入不同绑定值
        return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))
    }
}

let objF = {
    name: '张三',
    age: 10,
    objFun: function(form, to) {
        console.log('姓名:', this.name + ' ,年龄:' + this.age + ' ,来:' + form + ' ,去:' + to)
    }
}
let obj = {
    name: '李四',
    age: 8
}
objF.objFun.myCall(obj, '广州', '广西')
objF.objFun.myApply(obj, ['上海'])
objF.objFun.myBind(obj, ['北京'])()