call,apply的原理以及实现方式

call、apply、bind都是用来改变函数this的指向的

call、apply在改变函数this指向的同时,会调用函数,而bind则是返回一个新的函数,不会调用

call、bind 和 apply 之间的区别,则体现在对入参的要求上。前者只需要将目标函数的入参逐个传入即可,后者则希望入参以数组形式被传入。

了解了三者的作用机制,先看看例子

var student = {
  name: 'xiaoming'
}

function showName() {
  console.log(this.name);
}

showName.call(student); // xiaoming

结合 call 方法的特性,我们首先至少能想到以下两点:

call 是可以被所有的函数继承的,因为 JS 中每个函数的原型都指向Function.prototype对象(JS基于原型链的继承),所以 call 方法应该被定义在 Function.prototype 上;
call 方法做了两件事:
改变 this 的指向,将 this 绑定到第一个入参指定的的对象上去;
根据输入的参数,执行函数。
结合这两点,我们一步一步来实现 call 方法。首先,改变函数位置

var student = {
    name: 'xiaoming',
    function showName() {
      console.log(this.name);
    }
}
student.showName(); // xiaoming

然后根据这个思路我们有以下代码

var student = {
    name: "xiaoming"
};
function showName() {
    console.log(this.name);
}
Function.prototype.myCall = function(context, ...args){
    context = context || window;
    context.fn = this;
    context.fn(...args);
    delete context.fn;
}
showName.myCall(student)

这里context.fn = this;比较难理解,但是看后面调用showName.myCall(student)就比较好理解了
apply的实现原理差不多

var student = {
    name: "xiaoming"
};
function showName() {
    console.log(this.name);
}
Function.prototype.myCall = function(context, [...args]){
    context = context || window;
    context.fn = this;
    context.fn([...args]);
    delete context.fn;
}
showName.myCall(student)

bind有些不同 下回再说

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容