call

call 是属于所有 Function 的方法,也就是 Function.prototype.call。

1
2
fun.call(thisArg[,arg1[,arg2,…]]);

使用 call 调用函数并且指定 this

1
2
3
4
5
6
7
8
9
var obj = {
a: 1
}
function foo(b, c){
this.b = b;
this.c = c;
console.log(this.a + this.b + this.c);
}
foo.call(obj,2,3); // 6

call 实现继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + ":" + this.age);
}
}
function Student(name, age, job){
Person.call(this, name ,age);
this.job = job;
this.say = function(){
console.log(this.name + ":" + this.age + " " + this.job);
}
}
var me = new Student("axuebin",25,"FE");
console.log(me.say()); // axuebin:25 FE

apply

apply 也是属于所有 Function 的方法,也就是 Function.prototype.apply。

1
fun.apply(thisArg, [argsArray])

和 call 用法一样,只是参数不同,call 的参数是列表,将每个参数都列出来;apply 的参数是数组,将每个参数放到一个数组中

完整的 apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Function.prototype.myApply=function(context){
// 获取调用`myApply`的函数本身,用this获取,如果context不存在,则为window
var context = context || window;
var fn = Symbol();
context[fn] = this;
//获取传入的数组参数
var args = arguments[1];
if (args == undefined) { //没有传入参数直接执行
// 执行这个函数
context[fn]()
} else {
// 执行这个函数
context[fn](...args);
}
// 从上下文中删除函数引用
delete context.fn;
}

bind

bind()方法创建一个新的函数,当被调用时,将其 this 关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

1
2
fun.bind(thisArg[, arg1[, arg2[, ...]]])

例子:

1
2
3
4
5
6
7
8
9
10
function Person(name){
this.name = name;
this.say = function(){
setTimeout(function(){
console.log("hello " + this.name);
}.bind(this),1000)
}
}
var person = new Person("axuebin");
person.say(); //hello axuebin

总结

  • 三者都是用来改变函数的 this 指向
  • 三者的第一个参数都是 this 指向的对象
  • bind 是返回一个绑定函数可稍后执行,call、apply 是立即调用
  • 三者都可以给定参数传递
  • call 给定参数需要将参数全部列出,apply 给定参数数组