Javascript原生实现call/apply/bind

// call/apply/bind的原生js实现
// call和apply都是一次性且立即调用的
// bind是永久绑定到一个新函数,并不会立即调用

// 原生js实现bind函数
// 所有的函数都要有bind方法,所以要定义在Function的原型对象上
Function.prototype.myBind = function(objThis,...params){
    // objThis是要绑定的this对象,...params是因为参数数量不确定才用解构语法
    const thisFn = this;//当前调用的函数,例如fn.myBind()就把fn保存到thisFn
    let funcForBind = function(...secondParams){ // 要返回的函数
        // 判断函数是否是用new function生成的
        const isNew = this instanceof funcForBind
        const thisArg = isNew?this:objThis //this的指向
        // 绑定好this和参数返回到外层,暂时用call绑定,call也可以原生实现
        return thisFn.call(thisArg,...params,...secondParams)
    }
    // 绑定原型
    funcForBind.prototype = Object.create(thisFn)
    return funcForBind //返回绑定好的函数
} 
// 原生js实现call函数
Function.prototype.myCall = function(objThis,...params){
    // 先判断objThis,如果未传入则将this指向window
    if(objThis===null || objThis==undefined){
        objThis = window
    }
    const specialMethod = Symbol('anything');//不重复的方法
    // 将这个不重复的方法作为objThis的一个属性,属性值就是要绑定this的那个函数
    objThis[specialMethod] = this // this就是需要绑定this的函数
    // 调用函数并且将结果返回
    let result = objThis[specialMethod](...params)
    // call是一次性的,所以调用完之后要删除这个新增加的属性
    delete objThis[specialMethod]
    return result // 返回结果
}
// 原生js实现apply函数
// apply函数与call函数基本一致的,只是传入的参数是个数组
// 除了这两行,都与call函数一致 
Function.prototype.myApply = function(objThis,arr){
    // ....
    let result = objThis[specialMethod](...arr) // 解构传入的数组
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容