今天在mqyqingfeng点击这里的githubBlog上看到有关JS的bind的模拟实现,于是也跟着一起实现了一遍,需要更加详细的了解的话,也建议前往前辈的Blog学习,感谢。

以下是我学习后进行模拟的实现方式。


bind函数
1
2
3
4
5
6
7
8
9
var foo ={
value: 1
}
function bar() {
console.log(this.value)
}
var bindFoo = bar.bind(foo)
// bind不会立即执行
bindFoo(); //1


我们可以总结得到,bind函数不同于call、apply,它会返回一个未执行的函数,并且等待你的执行

于是我们根据此做出第一版模拟



第一版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var foo ={
value: 1
}
function bar() {
console.log(this.value)
}
Function.prototype.bind2 = function(context) {
var self = this;
return function() {
self.apply(context)
}
}
var result = bar.bind2(foo)
result(); // 1
上面我们模拟出来对于this的指向问题,接下来,我们继续对它的传递参数进行处理 我们先来看一下原生bind的处理与效果
1
2
3
4
5
6
7
8
9
10
11
12
13
var foo ={
value: 1
}
function bar(name, age) {
console.log(name) // Jayant
console.log(age) // 23
console.log(this.value) //1
}
// 此处传了部分参数
var bindFoo = bar.bind(foo, 'Jayant')

// 再传部分参数
bindFoo(23)

第二版
1
2
3
4
5
6
7
8
9
10
11
Function.prototype.bind3 = function (context) {
var self = this;
// 先接受一遍第一次的参数,
// 第二次调用时传递的在return的function中处理
var args = Array.prototype.slice.call(arguments, 1)
return function() {
var bindArr = Array.prototype.slice.call(arguments)
// 处理传入的参数;
return self.apply(context, args.concat(bindArr));
}
}
我们选择将参数在其中划分出来,二步处理,完成了bind参数问题

最终版

处理有关bind函数的new问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Function.prototype.bind4 = function(context) {
if(typeof this !== 'function') {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");

}
var self = this;
var args = Array.prototype.slice.call(arguments, 1);

var fNOP = function () {};

var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}

fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
}