call、apply、bind 的用法以及区别
1.共同作用
- 改变this的指向
2.区别之处
-
call
、apply
的区别:接受参数的方式不一样。call 接收多个参数
Function.call(obj,[param1[,param2[,…[,paramN]]]])
apply 接收一个数组列表
Function.apply(obj[,argArray])
-
bind
:不立即执行。而apply
、call
立即执行。Function.bind(thisArg[, arg1[, arg2[, ...]]])
//接收参数的方式不同
let name = 'windowObj';
function func1(age){
console.log(this.name,age);
}
let obj = {name:'newObj'};
//调用原生方法
func1(18) //输出 windowObj18
//改变this指向
func1.call(obj,22) //输出 newObj22
func1.apply(obj,[22]) //输出 newObj22
let func2 = func1.bind(obj,22); //bind本身不会调用方法
func2() //输出 newObj22 或者直接写 func1.bind(obj,22)() 也可以调用
3.具体分析一(改变函数体内 this 的指向)
function Person(name){
this.name = name;
}
Person.prototype = {
constructor: Person,
showName: function(){
console.log(this.name);
}
}
var person = new Person('tom');
person.showName();
新建一个对象
var animal = {
name: 'jerry'
}
我想让 person.showName()
运行后name变成jerry,就需要改变this
的指向
person.showName.call(animal);
person.showName.apply(animal);
person.showName.bind(animal)();//不会立即执行,需要调用
4.具体分析二(call、apply的区别:接受参数的方式不一样。)
var arr = [1,5,9,3,5,7];
// apply的第二个参数必须是一个包含多个参数的数组(或类数组对象)
Math.max.apply(Math, arr);
Math.max.call(Math, 1,5,9,3,5,7);
Math.min.apply(Math, arr);
Math.min.call(Math, 1,5,9,3,5,7);
5.call 和 apply 的应用场景
5.1call 的使用场景
- 1、对象的继承
function superClass () {
this.a = 1;
this.print = function () {
console.log(this.a);
}
}
function subClass () {
superClass.call(this);
this.print();
}
subClass();
// 1
subClass 通过 call 方法,继承了 superClass 的 print 方法和 a 变量。此外,subClass 还可以扩展自己的其他方法。
- 2、借用方法
还记得刚才的类数组么?如果它想使用 Array 原型链上的方法,可以这样:
let domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
这样,domNodes 就可以应用 Array 下的所有方法了。
5.2 apply 的一些妙用
- 1、Math.max。用它来获取数组中最大的一项。
let max = Math.max.apply(null, array);
//获取数组中最小的一项
let min = Math.min.apply(null, array);
- 2、实现两个数组合并。
在 ES6 的扩展运算符出现之前,我们可以用 Array.prototype.push来实现
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
6. 最后总结
call
和 apply
的主要作用,是改变对象的执行上下文,并且是立即执行的。它们在参数上的写法略有区别。
bind
也能改变对象的执行上下文,它与 call
和 apply
不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。
欢迎交流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gzBFw9fV-1627702834105)(3.call_apply_bind用法和区别.assets/image-20210728210314596.png)]
在参数上的写法略有区别。
bind
也能改变对象的执行上下文,它与 call
和 apply
不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。