JS - call、apply、bind

  1. 相同点

    • 功能目的相同bindcallapply都是用于改变函数内部this的指向,使得函数可以在特定的对象上下文中被调用,从而能够访问和操作该对象的属性。

    • 都和函数调用相关:它们都是函数对象的方法,并且在函数调用的场景下发挥作用,通过这些方法能够灵活地控制函数执行时的this指向。

  2. 区别

    调用方式、参数传递形式、返回值不同

         call 和 apply:它们会立即执行函数,并返回函数的执行结果。
         bind:它并不立即执行函数,而是返回一个新的函数。这个新函数在被调用时,内部的this指向已经被绑定到指定的对象上,并且可以根据bind时传递的参数情况来接收剩余的参数。

call

语法为函数名.call(对象, 参数1, 参数2,...)。它接受一个对象作为第一个参数,这个对象就是函数内部this要指向的对象。后面可以跟多个参数,这些参数会依次作为被调用函数的参数

function add(num1, num2) {
        return this.value + num1 + num2;

}

let obj = {value: 10};

console.log(add.call(obj, 20, 30));

这里add.call(obj, 20, 30)会将add函数内部的this指向obj,并将2030作为参数传递给add函数,最终返回60
apply语法为函数名.apply(对象, [参数数组])。它也接受一个对象作为第一个参数来指定this的指向,但第二个参数必须是一个包含函数参数的数组。

function add(num1, num2) {

        return this.value + num1 + num2;

}

let obj = {value: 10};

console.log(add.apply(obj, [20, 30]));

同样是将add函数内部的this指向obj,不过参数是通过一个数组[20, 30]的形式传递的,最终也返回60
bind语法为函数名.bind(对象, 参数1, 参数2,...)。它返回一个新的函数,这个新函数内部的this已经绑定到指定的对象上。可以立即调用这个新函数,也可以将它保存起来稍后调用。如果在bind时传递了参数,这些参数会被固定下来作为新函数的部分参数。

function add(num1, num2) {

        return this.value + num1 + num2;

}

let obj = {value: 10};

let newAdd = add.bind(obj, 20); console.log(newAdd(30));

首先add.bind(obj, 20)会返回一个新函数newAdd,这个新函数内部的this已经指向obj,并且第一个参数已经固定为20。当调用newAdd(30)时,相当于调用add函数,this指向obj,参数为2030,最终返回60

     3. 如何确定在 JavaScript 中使用 call、apply 还是 bind 方法?

          1) 是否需要立即执行函数

                ** 立即执行选择 call 或 apply

                        例如,你有一个函数用于计算两个数与对象中某个属性值的总和,并且你想在特定对象上下文中立即计算结果:

     function sum(num1, num2) {
         return this.value + num1 + num2;
     }
     let obj1 = {value: 10};
     let obj2 = {value: 20};
     // 使用call
     console.log(sum.call(obj1, 30, 40)); 
     // 使用apply
     console.log(sum.apply(obj2, [50, 60])); 

                ** 延迟执行选择 bind

                        例如,你有一个事件处理函数,需要在特定对象上下文中执行,但你只想先绑定this指向,等到事件触发时再执行:

     function handleClick() {
         console.log(this.name +'clicked');
     }
     let buttonObj = {name: 'Submit Button'};
     let boundHandleClick = handleClick.bind(buttonObj);
     document.addEventListener('click', boundHandleClick);

          2) 参数传递方式的便利性

                ** 参数逐个传递用 call

                        例如,有一个函数用于显示用户信息,包括姓名、年龄和城市,并且你想在某个用户对象的上下文中调用这个函数:                        

     function showUserInfo(name, age, city) {
         console.log(`Name: ${this.userName}, Name: ${name}, Age: ${age}, City: ${city}`);
     }
     let userObj = {userName: 'John'};
     showUserInfo.call(userObj, 'Alice', 25, 'New York');

                ** 参数以数组形式存在用 apply

                        例如,你有一个函数用于计算一组数字的总和,并且这些数字存储在一个数组中:

     function sumArray(numbers) {
         return numbers.reduce((total, num) => total + num);
     }
     let numberArray = [1, 2, 3, 4, 5];
     console.log(sumArray.apply(null, [numberArray])); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值