apply/call/bind 比较
- 参数: apply传入数组,call/bind传入多参数,bind还能在运行时继续传参
- 执行: apply/call立即执行,bind不会立马执行
apply的使用
用途
- 劫持方法,继承其他对象的属性.
- 可将数组参数转化为多参数(es6的运算扩展符也有这功能)
语法
fun.apply(thisArg, [argsArray])
- thisArg:fun 运行时指定 this
- argsArray:接收数组类型,执行时将数组转换为多参数
例子:
fun.apply(obj, [a,b,c])
=>fun(a,b,c)
- fun内涉及的this对象会指向obj
常见用途
- 数组最大最小值。
- Max.max和Max.min参数类型是多参数形式
如何实现apply?
// apply本身功能
console.log(Math.max(4,1,3));
console.log(Math.max.apply(null, [4,1,3]));
// 4
// 4
// 实现apply
Function.prototype.apply = function fn(context,param){
console.log(`my apply...`);
// 1. 修改方法内部this指向 => ctx
let ctx = context ? context : window;
ctx.fn = this; // this是当前方法,fn调用者是ctx(因此fn内this指向ctx)
// 2.参数转换: 只有数组需要
if(Array.isArray(param)){
// 字符串和数组相加,数组会自动转为字符串 例如'test ' + [1,2,3] => 'test 1,2,3'
return eval('ctx.fn(' + param + ')');
}else{
return ctx.fn();
}
}
// TEST
console.log(Math.max(4,1,3));
console.log(Math.max.apply(null, [4,1,3]));
// 4
// my apply...
// 4
call语法
fun.call(obj, param1, param2....)
- obj:代替fun里this对象
- params:接收多参数类型,没有任何转换
使用场景
[].slice.call(arguments)
需要先了解slice语法
slice(startIndex, endIndex)
切片数组,原数组不变,返回新数组- startIndex 默认是0,endIndex 默认是最后元素下标
- slice() 返回整个数组
- slice(1) 返回index=1开始到最后元素的数组
a=['a','b','c'];
b=a.slice();
c=a.slice(1);
console.log('a=',a);
console.log('b=',b);
console.log('c='