手写一个bind函数

我们先看代码,bind 函数的使用方法

        function test(a, b, c) {
            console.log(a, b, c);
            console.log('this', this)
            return '我是原函数的返回值'
        }
        // 普通执行
        const result = test(1, 2, 3); // 这里this 指向windows
        //  通过bind 改变this 指向
        const bindResult = test.bind({
            name: '张三'
        }, 7, 77, 777)
        //  执行bind 的返回函数
        const bindTest = bindResult(); //  这里this,指向张三
		// 打印一下,bind函数改变this指向后的test 返回值
        console.log('result', result)
        console.log('bindTest', bindTest);

执行代码,可以输出以下结果
在这里插入图片描述
我们可以发现bind 的三个特点:
1.改变this的指向,test的函数原来指向window ,经过bind函数改变了this指向,指向了{name:‘张三’}这个对象
2.bind函数的第一个参数是返回值,后边的参数是 test函数需要接收的参数 的值
3. bind函数改变this指向后,返回值没有变,执行result 和执行 bindTest 都返回

如何手写一个bind函数呢?
我们先把bind函数的特点列出来:
1.改变this指向
2. 第一个参数是this的指向,后边的参数是,函数接收的参数 的值
3. 返回值不变
4. 在函数的原型上

  • 这样,我们先实现第3个和第4个特点,我们把自己创建的方法放到函数的原型上,并返回原来的值
Fucntion.prototype.myBind = function (){
 	const self = this // 我们把原来的this保存,保证返回值不变
	return function(){
		return self() // 这样我们就实现了 3,4 两个特点。
	}
}
  • 我们在实现1,2个特点。改变 this的指向,指向第一个参数,以及后边的参数
  • 第一步我们先获取参数 传进来的参数,可以通过arguments类数组获取,
Fucntion.prototype.myBind = function (){
 	const self = this // 我们把原来的this保存,保证返回值不变
	
	// 传进来的参数,可以通过arguments类数组获取, 
	// const args = arguments 
	// 例如 : test.myBind({name:'张三'},7,7,777);  这里就打印出来类数组 Arguments:[{name:'张三'},7,7,777,caller:f......] 	
	// 但是类数组不是数组,我们不能直接用, 所以我们要把类数组,转换成数组
	const args = Array.prototype.slice.call(arguments) // [{name:'张三'},7,7,777]
	return function(){
		return self() // 这样我们就实现了 3,4 两个特点。
	}
}
  • 第二步,我们获取传参的第一个参数,并且吧,剩下的参数,保存并返回
  • 我们使用数组的shift() 方法来实现获取数组的第一个参数,并保证 原数组 删除第一个参数
Fucntion.prototype.myBind = function (){
 	const self = this // 我们把原来的this保存,保证返回值不变
	
	// 传进来的参数,可以通过arguments类数组获取, 
	// const args = arguments 
	// 例如 : test.myBind({name:'张三'},7,7,777);  这里就打印出来类数组 Arguments:[{name:'张三'},7,7,777,caller:f......] 	
	// 但是类数组不是数组,我们不能直接用, 所以我们要把类数组,转换成数组
	const args = Array.prototype.slice.call(arguments) // [{name:'张三'},7,7,777]
	// 我们定义一个变量,是args的第一参数
	const thisValue = args.shift() 	
	return function(){
		return self() // 这样我们就实现了 3,4 两个特点。
	}
}
  • 最后一步,我们把this 指向 传入参数的第一个参数 我们使用apply 来改变this 的指向 和,返回后续的参数

实现一个bind 方法 ,完整代码:

Fucntion.prototype.myBind = function (){
 	const self = this // 我们把原来的this保存,保证返回值不变
	
	// 传进来的参数,可以通过arguments类数组获取, 
	// const args = arguments 
	// 例如 : test.myBind({name:'张三'},7,7,777);  这里就打印出来类数组 Arguments:[{name:'张三'},7,7,777,caller:f......] 	
	// 但是类数组不是数组,我们不能直接用, 所以我们要把类数组,转换成数组
	const args = Array.prototype.slice.call(arguments) // [{name:'张三'},7,7,777]
	// 我们定义一个变量,是args的第一参数
	const thisValue = args.shift() 	
	return function(){
		return self.apply(thisVlaue,args) // 这样我们就实现了 3,4 两个特点。
	}
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值