一、bind 方法的作用
1、修改 this 指向
请看如下代码:1
2
3const $ = document.querySelector
const div = $('div')
// Uncaught TypeError: Illegal invocation
这段代码报类型错误,因为window对象下并没有querySelector方法。可以用bind解决,代码如下:1
2
3const $ = document.querySelector.bind(document)
const div = $('div')
// 返回结果 <div>......</div>
其他实现方式:1
2
3const $ = document.querySelector
const div = $.call(document,'div')
// 返回结果 <div>......</div>
call 和 apply 函数的缺陷是不能返回一个新方法。
2、可以实现偏函数的效果
bind方法可以返回一个新函数,而且可以在绑定的时候传入其他参数,比如:1
2
3const sum = (...args) => args.reduce((prev,next) => prev+next, 0)
const sum2 = sum.bind(null, 1)
console.log(sum2(1, 2)) // 4
3、bind 多次时 this 总是指向第一次 bind 的对象
运行如下代码:1
2
3
4
5
6
7
8
9
10
11const getName = function () {
console.log(this.name)
}
const p1 = {
name:'zhangsan'
}
const p2= {
name: 'lisi'
}
const name = getName.bind(p1).bind(p2)
name() // zhangsan
4、绑定构造函数
运行如下代码:1
2
3
4
5
6
7
8
9
10
11
12function Person (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
console.log(this.firstName + this.lastName)
}
const p = new Person('zhang', 'san') // zhangsan
const P = Person.bind(null, 'li')
const p3 = new P('si') // lisi
console.log(p instanceof Person) // true
console.log(p3 instanceof Person) // true
从如上结果可以看出,bind
实现中要根据当前调用函数 this
是否是被绑定函数的实例,如果是,修改 this
为当前调用者的 this
二、bind 方法的实现
语法:
fun.bind(thisArg[, arg1[, arg2[, ...]]])
参数:thisArg
-> 调用绑定函数时作为this参数传递给目标函数的值。
arg1, arg2, ... ->
当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
返回值:返回由指定的this
值和初始化参数改造的原函数拷贝
1、修改 this 指向
1 | Function.prototype.bind = function (oThis) { |
2、实现类似 curry 化的效果
1 | Function.prototype.bind = function (oThis) { |
3、绑定构造函数
1 | Function.prototype.bind = function (oThis) { |
4、mozilla 官方实现
1 | if (!Function.prototype.bind) { |