call/apply/bind的使用方法和区别

138 阅读2分钟

call/apply/bind的使用方法和区别

相同点

  • 第一个参数都是this要指向的对象
  • 这三个方法是函数方法,除了箭头函数之外都可以调用
  • 改变this指向
  • 至少有一个参数

区别

call:有多个参数,除第一个参数是this要指向的对象外,其余参数都是该函数需要的参数,且至少有一个参数

apply:有两个参数,除第一个参数是this要指向的对象外,第二个参数是数组 且至少有一个参数

bind:bind返回的是一个函数

示例:


 <script>
    const obj1 = {
        name: 'jack'
    }
    const obj2 = {
        name: 'rose'
    }

    function hi(msg1, msg2) {
        console.log(`${msg1}+${msg2}+${this.name}`)
        // 打印结果
        // 18+好看+rose
        // 19+漂亮+rose
        // 20+帅+jack
    }
    hi.call(obj2, 18, '好看')
    hi.apply(obj2, [19, '漂亮'])
    const hiBind = hi.bind(obj1)
    hiBind(20, '帅')
</script>
 

注意: 看到代码示例,我们首先应该想到的是在hi这个函数中,我们打印的this.name的this指向的是谁,在没有调用方法的时候,显而易见this指向的是window,但是window里面没有name这个属性,在这个时候,我们就需要通过改变This指向,来获取我们想要的属性

三种方法的使用场景

  1. bind使用场景: 在使用回调函数的时候,可以使用bind方法,在这里我们展示的回调函数是setTimeout方法,setTimeout方法中有callback,这个callback会改变this的指向,所以,我们在使用setTimeout方法的时候,需要绑定bind方法,来帮助我们将this指向我们需要的对象,获取我们想要的函数 示例:

let o = {
    name: 'test',
    fn() {
        console.log(this)
        console.log(this.name)
    }
}
setTimeout(o.fn.bind(o), 0)

  1. apply使用场景: 在前端拿到的数据为数组时,调用apply方法会更方便我们获得需要的对象和参数
//第一种
var array1 = [12 , "foo" , {name "Joe"} , -2458]; 
var array2 = ["Doe" , 555 , 100]; 
Array.prototype.push.apply(array1, array2); 
/* array1 值为  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */


//第二种
//**获取数组中的最大值和最小值**
var  numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(Math, numbers),   //458

  1. 使用场景:
//**获取数组中的最大值和最小值**
var maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

//第二种:
var a = Object.prototype.toString;

console.log(a.call("aaa"));
console.log(a.call(1));
console.log(a.call(true));
console.log(a.call(null));
console.log(a.call(undefined));
console.log(a.call([]));
console.log(a.call(function() {}));
console.log(a.call({}));