原生bind函数,创建一个新函数,新函数的this指向bind的第一个参数,剩下的参数作为实参传入目标函数中。同时,需要知道的是,新函数可以当做构造函数使用
function func(...arg) {
console.log(this)
console.log(arg)
}
func.prototype.getName = function () {
console.log(this.name)
}
var obj = { name: 'test' }
var fn1 = func.bind(obj, 1, 2, 3) // 原生bind
fn1() // {name: 'test'} [1,2,3]
var f1 = new fn1()
console.log(f1) // func () { _proto_:getName:f() constructor:f func(...arg) }
下面我们写自己的bind函数,需要将该函数绑定到Function的原型上
Function.prototype.myBind = function (thisArg, ...arg) {
let self = this
return function () {
self.apply(thisArg, [...arg])
}
}
function func(...arg) {
console.log(this)
console.log(arg)
}
func.prototype.getName = function () {
console.log(this.name)
}
var obj = { name: 'test' }
var fn1 = func.bind(obj, 1, 2, 3) // 原生bind
fn1() // {name: 'test'} [1,2,3]
var f1 = new fn1()
console.log(f1) // func () { _proto_:getName:f() constructor:f func(...arg) }
var fn2 = func.myBind(obj, 1, 2, 3) // 自定义myBind
fn2() // {name: 'test'} [1,2,3]
由此,我们自定义myBind函数实现了bind函数的基本功能,创建一个新函数,新函数的this指向myBind的第一个参数,剩下的参数作为实参传入目标函数。
但是,此时的myBind函数创建的新函数并不能当做构造函数使用,为了解决此问题,我们需要将myBind函数中的prototype指向目标函数的prototype,constructor也需要指向目标函数
Function.prototype.myBind = function (thisArg, ...arg) {
let self = this
let bound = function (...list) {
self.apply(thisArg, [...arg, ...list])
}
bound.prototype = Object.create(self.prototype)
bound.prototype.constructor = self
return bound
}
function func(...arg) {
console.log(this)
console.log(arg)
}
func.prototype.getName = function () {
console.log('222')
}
var obj = { name: 'test' }
var fn2 = func.myBind(obj, 1, 2, 3) // 自定义myBind
fn2() // {name: 'test'} [1,2,3]
var f2 = new fn2()
f2.getName() // 222