共同点: call()、apply()和bind()都是改变函数内部的this指向,第一个参数也都放的是要改变this对象
不同点:
(1)主要在第二个参数上,call()从第二个开始放的是正常的参数,而apply()放的是数组 ,bind()返回的是函数
(2)call()、apply()当第一个参数为 null、undefined的时候,默认指向window。
(3)bind()不会立即执行,call()、apply()直接调用
案例:
//有只猫叫小黑,小黑会吃鱼
const cat = {
name :'小黑',
eatFish(...args) {
console. log('this指向=>',this);
console.1og('...args”,args);
console. log(this.name + '吃鱼');
},
}
//有只狗叫大毛,大毛会吃骨头
const dog={
name: '大毛',
eatBone(...args) {
console. log('this指向=>',this);
console.1og('...args”, args);
console. log(this.name + '吃骨头');
},
}
console.1og(================ call =====================');
//有一天大毛想吃鱼了,可是它不知道怎么吃。怎么办?小黑说我吃的时候喂你吃
cat.eatFish.call(dog, '汪汪汪’, 'call')
//大毛为了表示感谢,决定下次吃骨头的时候也喂小黑吃
dog.eatBone.call(cat,'喵喵喵 ','call')
console.1og(================ apply =====================');
cat.eatFish.apply(dog, [汪汪汪',' apply'])
dog.eatBone.apply(cat, ['喵喵喵',' apply'])
console.1og(================ bind =====================');
//有一天他们觉得每次吃的时候再暧太麻烦了。于脆直接教对方怎么吃
const test1 = cat.eatFish.bind(dog,汪汪汪’, ' bind')
const test2 = dog. eatBone.bind(cat, '喵喵喵’, ' bind')
test1()
test2()
应用场景:
1.求数组中的最大和最小值
var arr = [1, 2, 3, 89, 46];
var max = Math.max.apply(null, arr); // 89
var min = Math.min.apply(null, arr); // 1
2.将类数组转为数组
var trueArr = Array.prototype.slice.call( arrayLike );
3.数组追加
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var total = [].push.apply(arr1, arr2); // 6
arr1 = [1, 2, 3, 4, 5, 6]
arr2 = [4, 5, 6]
4.判断变量类型
function isArray(obj){
return Object.prototype.toString.call(obj) == '[Object Array]';
}
// isArray([]) => true
// isArray('yw') => false
5.利用call和apply做继承
fucntion Person(name, age){
// 这里的this都指向实例
this.name = name;
this.age = age;
this.sayAge = function(){
console.log(this.age)
}
}
function Female(){
Person.apply(this, arguments); // 将父元素所有方法在这里执行一遍就继承了
}
var female = new Female('yw', 27);
总结:
1.当我们使用-个函数需要改变this指向的时候才会用到call apply bind
2.如果你要传递的参数不多,则可以使用fn.call(thisobj, arg1, arg2 …)
3.如果你要传递的参数很多,则可以用数组将参数整理好调用fn. apply(this0bj, [arg1, arg2 …)
4.如果你想生成一个新的函数长期绑定某 个函数给某个对象使用,则可以使用const newFn =
fn. bind(this0bj); newFn(arg1, arg2…)