手写bind函数
will.wei 8/3/2021 bind函数
# 手写bind函数
bind是function原型对象上的函数,即每个函数都可以调用bind函数。其作用是用于创建一个新函数。
# bind函数概念
bind是function原型对象上的函数,即每个函数都可以调用bind函数。其作用是用于创建一个新函数A。在bind被调用时,这个新函数A的this被指定为bind()的第一个参数,而bind()传入的其余的参数将作为新函数的参数,供调用时使用。
this.x = 9; // 在浏览器中,this 指向全局的 "window" 对象
var module = {
x: 81,
getX: function() { return this.x; }
};
var retrieveX = module.getX;
retrieveX(); // 9
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
module.getX(); // 81
//bind函数将this指向module
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 手写bind函数
手写bind之前先看看bind函数的使用逻辑:
function foo() {
this.b = 100;
return this.a;
}
let func = foo.bind({a: 1});
func(); // 1
new func(); // foo { b: 100 }
1
2
3
4
5
6
7
2
3
4
5
6
7
- 作用对象首先是个函数
- 第一个参数作为新函数的this,剩下参数作为新函数的参数
- 当new 一个新的新函数的实例的时候,新创建的实例对象要绑到当前this上,新实例的原型对象要指向当前函数的原型
Function.prototype.myBind = function(oThis){
// 作用对象首先是个函数
if(typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
// 第一个参数作为新函数的this
let aArgs = Array.prototype.slice.call(arguments, 1);
let fToBind = this;
let fNOP = function() {};
let fBound = function(){
return fToBind.apply(
fNOP.prototype.isPrototypeOf(this) ? this:oThis, // 如果是直接调用新函数,this指向第一个参数;如果是new的新函数,this指向新创建的实例对象,且新实例的原型对象要指向当前函数fNOP的原型
aArgs.concat(Array.prototype.slice.call(arguments))); // 剩下参数作为新函数的参数
}
if(this.prototype) {
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP(); //返回新函数的原型对象是调用函数的一个实例,这样new的新对象也能够获取调用函数的属性和方法
return fBound;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
查看结果
function foo() {
this.b = 100;
return this.a;
}
let func = foo.myBind({a: 1});
func(); // 1
let nf = new func(); // foo { b: 100 }
nf.__proto__ // foo {}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8