JavaScript基本功之apply/call/bind使用和实现原理

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='

猜你喜欢

转载自blog.csdn.net/qubes/article/details/134334639