Loading

js中bind,call,apply的作用以及模拟实现

apply的实现

apply的特点

  • 只有两个参数 第一个参数是需要指向的对象 使用一个数组来作为该函数的第二个参数
  • 没有传入参数就默认指向window
Function.prototype.myApply = function(context){  
    context = context ? Object(context) : window; //
    let fn = Symbol()
    context[fn] = this // this是当前调用了call的函数
    let res = context[fn](...arguments[1]) //执行函数
    delete context[fn]
    return res
}
let obj1 = {
    test(a,b,c){
        console.log(this,a,b)
    }
}
obj1.test.myApply(obj1,[4,5])// { test: [Function: test], [Symbol()]: [Function: test] } 4 5

call的实现

call的特点

  • call其实是apply的一个语法糖,他们的作用都是用于改变上下文的指向,区别在于,call接受多个参数,而apply接受的是一个数组
// call的实现
Function.prototype.myCall = function(context,...rest){  
    context = context ? Object(context) : window; //
    let fn = Symbol()
    context[fn] = this // this是当前调用了call的函数
    let args = rest   // 剩余参数数组
    let res = context[fn](...args) //执行函数
    delete context[fn]
    return res
}
let obj1 = {
    test(a,b,c){
        console.log(this,a,b)
    }
}
obj1.test.myCall(obj1,4,5) // { test: [Function: test], [Symbol()]: [Function: test] } 4 5

bind的实现

  • bind的实现与call类似 只是返回改变了this指向的函数,并不执行
Function.prototype.myBind = function(context){  
    if(typeof this != 'function') {
        throw new TypeError('Error');
    }
    let _this = this;
    let args = [...arguments].slice(1);//拿到传入的参数
    return function F() {
        if(this instanceof F) { // 判断this在F的原型链上没
            return new _this(...args,...arguments);
        }
        return _this.apply(context,args.concat(...arguments))
    }
}
obj1.test.myBind(obj1,4,5)() // { test: [Function: test] } 9
posted @ 2021-01-16 17:20  不吃苦瓜^  阅读(143)  评论(0编辑  收藏  举报