实现 call、apply 和 bind 方法
程序员文章站
2022-07-03 08:58:55
call、apply 和 bind本质上都是要改变 this 的指向,在实现过程中一定要时刻搞清楚 this 的指向首先考虑一下这个场景function show() {console.log(this.name); // undefined}const person = {name: 'white_give'};如果不用call、apply 和bind,如何让 show 方法里的 this 指向 person 对象呢?可以像下面这样做const person = {nam...
call、apply 和 bind本质上都是要改变 this 的指向,在实现过程中一定要时刻搞清楚 this 的指向
首先考虑一下这个场景
function show() {
console.log(this.name); // undefined
}
const person = {
name: 'white_give'
};
如果不用call
、apply
和bind
,如何让 show
方法里的 this
指向 person
对象呢?
可以像下面这样做
const person = {
name: 'white_give',
show: function () {
console.log(this.name);
}
};
其实我们手写实现 cal
l 、 apply
和bind
时也是这个思路
call
call
的第一个参数为普通函数,其余参数则为该函数的参数
Function.prototype.myCall = function (ctx, ...args) {
/**
* this 指向 myCall 函数的调用者
* ctx 为 this 要指向的对象
*/
ctx = ctx || window
ctx.fn = this; // 相当于给 person 对象增加了一个 fn 属性,属性值是 show 函数
const result = ctx.fn(...args);
delete ctx.fn;
return result;
}
apply
apply
的第一个参数是普通函数,第二个则为该函数的参数祖成的数组
Function.prototype.myApply = function (ctx, args) {
/**
* this 指向 myCall 函数的调用者
* ctx 为 this 要指向的对象
*/
ctx = ctx || window
ctx.fn = this; // 相当于给 person 对象增加了一个 fn 属性,属性值是 show 函数
const result = args.length > 0? ctx.fn(...args) : ctx.fn();
delete ctx.fn;
return result;
}
bind
bind
跟call
差不多,最大的区别是他返回的是一个函数,需要再次调用才生效
Function.prototype.myBind = function (ctx) {
const args = Array.prototype.slice.call(arguments, 1);
const self= this
const fun= function () {};
const fn = function () {
const total = args.concat(...arguments)
if(this instanceof self) {
self.apply(this, total )
} else {
self.apply(ctx, total )
}
}
const fn= function() {
let total = arg.concat(arguments)
// 如果使用 new 关键字,这里的 this 指向的是 newFn 对象
if (this instanceof fn) {
// 将 myBind 调用者的 this 改为 newFn 对象
that.apply(this, args);
} else {
that.apply(ctx, args);
}
}
fun.prototype = this.prototype;
fn.prototype = new fun();
return fn;
}
本文地址:https://blog.csdn.net/qq_29850249/article/details/110209299