欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

实现 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'
};

如果不用callapplybind,如何让 show 方法里的 this 指向 person 对象呢?
可以像下面这样做

const person = {
	name: 'white_give',
    show: function () {
    	console.log(this.name);
    }
};

其实我们手写实现 call 、 applybind 时也是这个思路

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

bindcall差不多,最大的区别是他返回的是一个函数,需要再次调用才生效

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