看看真正的call方法,手撕代码实现

36 篇文章 1 订阅

我们现在先来看个小demo

			function fn(){
				let a = this.a
				console.log(a)
			}
			
			let obj = {
				a: 1,
				objFn: fn
			}
			
			let obj2 = {
				a: 2,
				// objFn: fn
			}
			
			obj.objFn()
			
			fn.call(obj2) //

打印结果:
在这里插入图片描述
我们的call方法其实就是改变函数的上下文,或者说call方法就是改变this指向的。注意,我们在obj2中没有引用fn方法,但是也是可以使用的。说明,call方法就只是提供上下文,并且调用函数。

那我们来手写实现一下代码:

// 1没有传递给函数的上下文,那就是默认为window
// 2防止以Function.protiType.call()的形式直接调用
Function.prototype.call = function(context = window,...args){
	// 防止以Function.protiType.call()的形式直接调用
	if(this === Function.prototype){
		return undefined
	}
	// 为什么需要使用symbol?
	// 因为在call方法提供的环境中没有fn()方法的引用
	// 如上文,在obj2中没有fn函数的引用
	// 所以我们使用symbol创建一个唯一的函数名,当做函数的临时引用
	
	// 我们在使用Symbol的时候需要时Symbol(),而不是new来调用构造函数
	// 两个symbol是不相同的
	const fnSymbol = Symbol()
	console.log(fnSymbol)
	context[fnSymbol] = this
	// 调用并销毁
	const reslut = context[fnSymbol](...args)
	delete context[fnSymbol]
	// 返回的是指向函数的返回值
	return reslut
}
小知识点:上文中用...args接受后面的所有函数,变相的以一个数组来接收函数,args是一个数组,但是使用...展开符进行操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值