语法
函数.apply(Object对象,[数组])
函数.call(Object,a1,a2,a3…)
函数.bind(Object,a1,a2,a3…)
三个语法相同点
call、apply、bind都是被一个函数调用;
Object参数:改变该函数的this对象
除Object参数外的其他参数(数组或者a1…):该函数所需要的参数
Object参数示例讲解
定义一个fn函数
var fn= function(a,b,c){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
}
如果直接调用函数fn(1,2,3),控制台运行结果如下:
Window {}
1
2
3
如果调用函数fn.apply(1,[2,7,9]); ,控制台运行结果如下:
Number {1}
2
7
9
经过上述两次调用结果的比较,你会发现console.log(this)代码输出的this值改变了,由window对象变成了Number对象,所以验证了Object参数是改变被执行函数的this对象 (call、bind方法中参数Object也是同样的作用)
不同点
-
函数.apply(Object对象,[数组])
apply第二个参数必须是一个数组,当传入函数时,会被扩展成多个参数。 扩展:类似与ES6语法中的…arr
比如上述执行函数 fn.apply(1,[2,7,9]),数组[2,7,9]就会扩展成多个参数2,7,9分别赋值给fn(a,b,c)方法中的a,b,c
-
函数.call(Object对象, a1,a2,a3)
相比apply,a1,a2,a3不可传数组进行扩展
-
函数.bind(Object,a1,a2,a3…)
执行完bind函数,返回的是绑定this以及参数的被执行函数
-
示例讲解
在控制台上执行bind函数且将结果赋值给bindfn
在控制台打印bindfn ,控制台运行结果如下:var bindfn = fn.bind(1,8,9,10)
ƒ (a,b,c){ console.log(this); console.log(a); console.log(b); console.log(c); }
从结果可看到:执行完bind函数,返回的是一个和fn一样的函数。
然后再在控制台执行bind函数返回的函数bindfn如下代码:
控制台运行结果为:bindfn(2,5,7,6)
从结果看出,输出的值并非是Number {2} 5 7 6,而是执行fn.bind(1,8,9,10) 代码时传进的参数,由此验证了:【执行完bind函数,返回的是绑定this以及参数的被执行函数】,即使以不同的参数再次调用该返回函数bindfn,执行结果也不会改变。Number {1} 8 9 10
-
apply示例用途
-
求数组[3,5,7,1,6]中的最大值:
我们知道执行
执行完得到最大值7。但现在要传入数组,则使用apply得到最大值Math.max(3,5,7,1,6)
Math.max.apply(null,[3,5,7,1,6] )
-
类的继承:使用apply可以实现类的继承,如下所示
现创建Animal类、Dog类,Dog类继承Animal类
var Animal = function(name){ this.name = name; console.log(this); console.log(this.name); } var Dog = function(name,color){ Animal.apply(this,arguments); }
注:Animal.apply(this,arguments);此句代码中,
this指代Dog类,
arguments数组是所有(非箭头)函数中都可用的局部变量,代表传入的参数集合
然后我们创建一个dog对象 【注:此时的arguments为: Arguments(2) [“dog name”, “orange”]】
控制台运行结果如下:var dog1 = new Dog("dog name",'orange');
由此看出Dog类继承了Animal类的属性以及方法。Dog {name: "dog name"} dog name