call,apply,bind手写面试题

目录

前言

一、call实现

二、apply实现

三、bind实现

特点区别


前言

call,apply,bind改变this指向 面试官最喜欢考的题

一、call实现

只要搞清楚this是什么情况就容易理解

function Person(name, price) {
			this.name = name
			this.price = price
			this.msg = function () {
				console.log('我叫' + this.name)
			}
		}

		let arg = {
			sex: '男',
			age: 20
		}

		// 向原型添加一个方法 使所有的函数都可以用此方法
		// thisArg(需要被添加属性或方法的对象)...arg(接受的参数)
		Function.prototype.myCall = function (thisArg = globalThis, ...arg) {
			//添加一个独一无二的值 以免thisArg里面有一样名字的属性会被覆盖掉
			const key = Symbol()
			//这个this指向他的调用者this为asg 调用myCall的函数里面的this会变成thisArg
			thisArg[key] = this
			// 将函数里面的形参赋值
			thisArg[key](...arg)
			// 删除多余都属性
			delete thisArg[key]
			//call的返回值是undefined
			return thisArg
		}

		console.log(Person.myCall(arg, '祁纤', '10000'))

二、apply实现

跟call同理

注意...运算符的使用

// 向原型添加一个方法 使所有的函数都可以用此方法
		// thisArg(需要被添加属性或方法的对象)...arg(接受的参数)
		Function.prototype.myApply = function (thisArg, arg) {
			// 如果thisArg不是很法值就返回对应环境的全局 如Window 
			if (!thisArg) {
				thisArg = globalThis
			}
            arg= arg? arg: []
			//添加一个独一无二的值 以免thisArg里面有一样名字的属性会被覆盖掉
			const key = Symbol()
			//这个this指向他的调用者this为asg 调用myCall的函数里面的this会变成thisArg
			thisArg[key] = this
			// 将函数里面的形参赋值
			thisArg[key](...arg)
			// 删除多余都属性
			delete thisArg[key]
            //apply的返回值是undefined
			return thisArg
		}

		console.log(Person.myApply(arg, ['祁纤', '10000']))

三、bind实现

,bind是返回一个绑定好的函数,就是返回一个函数,要考虑到使用new去调用,并且new的优先级比较高,所以需要判断new的调用,还有一个特点就是bind调用的时候可以传参,调用之后生成的新的函数也可以传参,效果是一样的,所以这一块也要做处理 因为上面已经实现了apply,这里就借用一下,实际上不借用就是把代码copy过来

let obj = {
			name: '祁纤',
			fun() {
				return this.name
			}
		}

		function Fun(bzd) {
			this.bzd = bzd
		}

		Function.prototype.myBind = function (context, ...args) {
			// 	// 保存一下this,防止this丢失
			let self = this
			// 以后函数可以传参...fnArgs
			return function fn(...fnArgs) {
				// instanceof用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
				// new 的时候,this指向new出来的实例,实例的__proto__指向fn的prototype
				if (this instanceof fn) {
					// 让this指向被new 出来的实例对象
					return new self(...args, ...fnArgs)
				}
				return self.apply(context, [...args, ...fnArgs])
			}
		}
		
		let fun = Fun.myBind(obj, '呜呜呜')
		fun()
		console.log(obj)

以上所有实现可以再加点判断啊,例如调用的不是function就返回或者抛出错误啊之类的.我这里就不处理了

以上就是apply,call,bind的实现了

特点区别

call() 方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。

apply() 方法使用一个指定的this值和单独给出的 一个或多个参数的数组 来调用一个函数。

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值