极简实现系列——手写bind

极简实现系列——是用最简单的代码实现一些常见的方法,目的是为了帮助理解原理,所以并没有考虑太多限制条件


之前写过call和apply的原理实现,bind的实现原理也类似。先来看看MDN上关于bind的介绍:

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

看个简单的例子:

let obj = {
    value: 1
}
function fn(a,b){
    console.log(this.value)
}
let fn2 = fn.bind(obj)
fn2() // 1 
 可以看出跟call/apply的区别就是bind是返回一个函数。我们根据之前在《自己简易实现系列——手写call和apply》中的思路,可以简易的写出第一版的代码

第一版

Function.prototype.myBind = function(context) {
	let that = this
	return function(){
		return that.apply(context)
	}
}

let obj = {
    value: 1
}
function fn(){
    console.log(this.value)
}
let fn2 = fn.myBind(obj)
fn2() // 1 输出1,说明改变指向成功

看到结果是可以了,粗糙的第一版已经完成了

第二版

bind是可以传参数的,而且通过bind创建的新函数也可以带参数。我们看一个例子:

let obj = {
    value: 1
}
function fn(a,b){
    console.log(this.value)
    console.log(a)
    console.log(b)
}
let fn2 = fn.bind(obj, 'a')
fn2('b') // 1 a b

可以看到bind很神奇,可以在创建的时候传一个参数,创建后的新函数调用时再传另一个~。 我们根据这个特性再来改造下

 

Function.prototype.myBind = function(context) {
	let that = this
	let arg =[].slice.call(arguments, 1)
	return function(){
		let arg2 = [].slice.call(arguments) // 此时的argument表示bind创建后的函数的参数
		return that.apply(context, arg.concat(arg2))
	}
}

let obj = {
    value: 1
}
function fn(a, b){
    console.log(this.value)
	console.log(a)
	console.log(b)
}
let fn2 = fn.myBind(obj, 'a')
fn2('b') // 1 a b

当然也可以用es6的rest参数来简化一下

Function.prototype.myBind = function(context, ...arg) {
	let that = this
	return function(...arg2){
		return that.apply(context, [...arg, ...arg2])
	}
}

let obj = {
    value: 1
}
function fn(a, b){
    console.log(this.value)
	console.log(a)
	console.log(b)
}
let fn2 = fn.myBind(obj, 'a')
fn2('b') // 1 a b

over~

当然bind还有一个比较复杂的特性就是当 bind 返回的函数作为构造函数的时候,bind绑定的this会失效,但是其他的参数依然有效 ,这部分内容等下次有时间再来完善~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值