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

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


call的使用
1
2
3
4
5
6
7
8
9
var foo = {
value: 1
}
function bar(name, age) {
console.log(name) // Jayant
console.log(age) // 23
console.log(this.value) // 1
}
bar.call(foo,'Jayant',23)


如果将bar()作为foo的属性:

那么我们也可以完成其this的改变

1
2
3
4
5
6
7
8
var foo = {
value: 1,
bar: function(){
console.log(this.value)
}
}
// 将bar作为属性放在foo上
foo.bar();

那么按照此思路,我们是不是也可以将大致的行为抽象称为

1
2
3
4
// 赋给属性--执行它--删除它
foo.fn = bar()
foo.fn()
delete foo.fn

于是我们根据我们的思路,实现第一版绑定实现:
第一版:

我们选择将该函数定义在Function原型上

1
2
3
4
5
6
7
8
9
10
11
12
Function.prototype.call2 = function(context) {
context.fn = this;
context.fn();
delete context.fn;
}
var foo = {
value: 1
}
function bar() {
console.log(this.value)
}
bar.call2(foo) // 1

我们在call2函数上将this赋予了context的fn属性,并且在执行之后删除它
其次call中还有参数的问题,按照我们的第一版实现,我们并不能传入参数 于是我们进一步进行参数的处理 第二版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Function.prototype.call3 = function(context) {
context.fn = this;
var args = [];

// 因为此处的arguments里边有参数,剥夺第一个的context方法,其余就是参数
for(var i =1,len=arguments.length;i<len;i++){
args.push(arguments[i])
}
<!--关键在于上边对于arguments参数的提取-->

context.fn(...args);
delete context.fn;
}
var foo = {
value: 1
}
function bar(name,age) {
console.log(name) // jayant2
console.log(age) // 23
console.log(this.value) // 1
}
bar.call3(foo,'jayant2',23)
于是我们完成了call3函数内的参数定义,传递问题
第三版 第三版,进行了函数的具体完善,this为空的情况,指向null,将值返回的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Function.prototype.call4 = function(context) {
<!--此处进行了传入this是否为空的情况-->
var context = context || window

context.fn = this;
var args = [];
// 因为此处的arguments里边有参数,剥夺第一个的context方法,其余就是参数
for(var i =1,len=arguments.length;i<len;i++){
args.push(arguments[i])
}
var result = context.fn(...args);
delete context.fn;
<!--进行了返回值处理-->
return result
}
var foo = {
value: 1
}
function bar(name,age) {
console.log(name) // jayant2
console.log(age) // 23
console.log(this.value) // 1
}
bar.call4(foo,'jayant4',23)
至此,以上就是进行call模拟的大致过程

庭院海边