加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

call, apply, bind的内部实现原理

发布时间:2020-12-14 04:24:53 所属栏目:大数据 来源:网络整理
导读:call,apply,bind都是改变函数执行的上下文,说的直白点就是改变了函数this的指向。不同的是:call和apply改变了函数的this,并且执行了该函数,而bind是改变了函数的this,并返回一个函数,但不执行该函数。 看下面的 例子1: var doThu = function(a,b) { co

call,apply,bind都是改变函数执行的上下文,说的直白点就是改变了函数this的指向。不同的是:call和apply改变了函数的this,并且执行了该函数,而bind是改变了函数的this,并返回一个函数,但不执行该函数。

看下面的例子1:

var doThu = function(a,b) {
    console.log(this)
    console.log(this.name)
    console.log([a,b])
}
var stu = {
    name: ‘xiaoming‘,doThu: doThu,}
stu.doThu(1,2) // stu对象 xiaoming [1,2]
doThu.call(stu,1,2]

由此可见,在stu上添加一个属性doThu,再执行这个函数,就将doThu的this指向了stu。而call的作用就与此相当,只不过call为stu添加了doThu方法后,执行了doThu,然后再将doThu这个方法从stu中删除。

下面来看call函数的内部实现原理:

Function.prototype.call = function(thisArg,args) {
    // this指向调用call的对象
    if (typeof this !== ‘function‘) { // 调用call的若不是函数则报错
        throw new TypeError(‘Error‘)
    }
    thisArg = thisArg || window
    thisArg.fn = this   // 将调用call函数的对象添加到thisArg的属性中
    const result = context.fn([...arguments].slice(1)) // 执行该属性
    delete context.fn   // 删除该属性
    return result
}

apply的实现原理和call一样,只不过是传入的参数不同而已。下面只给出代码,不做解释:

Function.prototype.apply = function(thisArg,args) {
    if (typeof this !== ‘function‘) { 
        throw new TypeError(‘Error‘)
    }
    thisArg = thisArg || window
    thisArg.fn = this
    let result
    if(args) {
        result = thisArg.fn(...args)
    } else {
        result = thisArg.fn()
    }
    delete thisArg.fn
    return result
}

bind的实现原理比call和apply要复杂一些,bind中需要考虑一些复杂的边界条件。bind后的函数会返回一个函数,而这个函数也可能被用来实例化:

Function.prototype.bind = function(thisArg) {
    if(typeof this !== ‘function‘){
        throw new TypeError(this + ‘must be a function‘);
    }
    // 存储函数本身
    const _this  = this;
    // 去除thisArg的其他参数 转成数组
    const args = [...arguments].slice(1)
    // 返回一个函数
    const bound = function() {
        // 可能返回了一个函数,我们可以 new F(),所以需要判断
        if (this instanceof F) {
            return new _this(...args,...arguments)
        }
        // apply修改this指向,把两个函数的参数合并传给thisArg函数,并执行thisArg函数,返回执行结果
        return _this.apply(thisArg,args.concat(...arguments))
    }
    return bound
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读