call、apply和bind方法的用法、区别和使用场景

本文介绍了JavaScript中call、apply和bind这三个方法的用途,主要用于改变函数执行时的上下文(this)指向。call接受参数列表,apply接收参数数组,bind则返回一个新函数,保留原函数的上下文但允许延迟执行。示例展示了它们在数组操作、获取最大值、判断数据类型等场景的应用,并强调了它们在参数传递上的灵活性。
摘要由CSDN通过智能技术生成

apply 和 call

在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。

JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

先来一个栗子:

function fruits() {}
 
fruits.prototype = {
    color: "red",
    say: function() {
        console.log("My color is " + this.color);
    }
}
 
var apple = new fruits;
apple.say();    //My color is red

但是如果我们有一个对象banana= {color : “yellow”} ,我们不想对它重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法:

banana = {
    color: "yellow"
}
apple.say.call(banana);     //My color is yellow
apple.say.apply(banana);    //My color is yellow

所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。

apply、call 的用法

前面讲了 apply、call 的作用,这里详细讲一下如何使用。

call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。

apply 的语法:

func.apply(thisArg, [argsArray])

参数讲解:

  • thisArg:必选的。在 func 函数运行时指定使用的 this 值。在非严格模式下,该参数指定为 nullundefined 时会自动替换为指向全局对象。
  • argsArray:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。

call 的用法类似。

apply、call 的区别

对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:

var func = function(arg1, arg2) {
     
};

就可以通过如下方式来调用:

func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])

其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

一句话总结两者的区别:

call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。

JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话:

  • 当你的参数是明确知道数量时用 call。

  • 而不确定的时候用 apply,然后把参数 push 进数组传递进去。

参数数量不确定时,函数内部也可以通过 arguments 这个伪数组来遍历所有的参数。

bind

bind 和 call/apply 有一个很重要的区别,一个函数被 call/apply 的时候,会立即执行函数,但是 bind 会创建一个新函数,不会立即执行

var obj = {
    x: 81,
};
 
var foo = {
    getX: function() {
        return this.x;
    }
}
 
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。

当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

如上,bind另一个重要的区别是,后面传入的这个参数列表可以分多次传入,call和apply则必须一次性传入所有参数。

示例:

var arr=[1,10,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3])
console.log(max(arr[4])); //12,分两次传参

可以看出,bind方法可以分多次传参,最后函数运行时会把所有参数连接起来一起放入函数运行。

应用场景

数组之间追加

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
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

判断数据类型

Object.prototype.toString.call()

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({}));

在这里插入图片描述

结尾

我是圆圆,如果我的文章对你的学习成长有所帮助,欢迎 点 赞 👍 支持,您的 点 赞 👍 支持是我进行创作和分享的动力!

如果有问题可以留言评论或者私信我,我都会一一解答~笔芯🤞

参考

  • https://www.cnblogs.com/coco1s/p/4833199.html#!comments
  • https://zhuanlan.zhihu.com/p/82340026
  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: bind、call和apply都是用来改变函数中this的指向的方法bind方法会返回一个新的函数,这个新函数的this指向被绑定的对象,但不会立即执行。 call和apply方法都是立即执行函数,并且都会改变函数中this的指向。它们的区别在于传入参数的方式不同,call方法是将参数一个一个传入,而apply方法是将参数放在一个数组中传入。 举个例子: ``` var obj = { name: 'Tom' }; function sayHello(age) { console.log('Hello, my name is ' + this.name + ', I am ' + age + ' years old.'); } var newSayHello = sayHello.bind(obj); newSayHello(18); // Hello, my name is Tom, I am 18 years old. sayHello.call(obj, 18); // Hello, my name is Tom, I am 18 years old. sayHello.apply(obj, [18]); // Hello, my name is Tom, I am 18 years old. ``` 以上代码中,我们定义了一个对象obj和一个函数sayHello。使用bind方法将sayHello函数中的this指向obj,并返回一个新的函数newSayHello。使用call和apply方法直接调用sayHello函数,并将this指向obj,同时传入参数18。 ### 回答2: bind和call apply都是JavaScript中用来改变函数执行上下文的方法,但它们有些许区别bind方法会创建一个新函数,其this值会被绑定到指定的对象上。它接收一个参数,即想要将函数绑定到的对象。如果绑定的函数参数存在,则会将绑定函数的参数传递给原始函数,同时返回绑定后的新函数。如果绑定的函数没有参数,则直接返回一个绑定后的新函数。bind方法并不会立即调用函数,而是返回一个函数引用,需要手动调用函数才会执行。 call和apply则是直接调用函数,并且可以指定函数执行上下文。它们最主要的区别在于传递参数的方式不同。call方法接收的参数是一个参数列表,即需要传递给函数的参数直接列出来一个一个传递。apply方法接收的参数是一个数组,即需要传递给函数的参数通过数组的方式传递。另外,如果函数没有参数,那么使用call和apply的方式没有区别。 因此,如果我们想要在不同的上下文中调用函数,可以使用bind方法,在其他时候可以使用call和apply方法。同时,由于bind方法会创建新的函数引用,可能会占用一些内存空间,因此可考虑使用call和apply方法。 ### 回答3: bind、call和applyJavaScript中三个非常重要的函数方法,它们都用于改变函数的this指向。虽然它们的作用类似,但是它们具体的使用方式有很大的不同。 bind()、call()和apply()都能够把一个函数的this指向指定为第一个参数中的对象,并且都可以传递多个参数给函数。具体差别如下: 1. bind():bind()方法常常用于多次调用同一函数,且该函数的this值不变。bind()方法会返回一个新函数,并且它的this值总是被指定为第一个参数。bind()方法的传参方式,与原函数相同,在调用时将参数以一个个单独的参数传入。 2. call():将具体的值,作为指定的this,传入并执行该函数。call()方法会在调用时执行指定函数,并且呈现出函数的this值为第一个参数的对象。call()方法的传参方式,将参数以一个个单独的参数传入。 3. apply():apply()的作用与call()类似,主要区别在于参数的传递方式,apply()会将参数直接传入数组。就是说,在调用apply()方法时,需要将需要绑定到this的对象作为第一个参数传入,第二个参数是一个数组、列表或类似数组的对象,该数组中的所有元素都将作为单独的参数传递给被调用的函数。 总之,bind()、call()和apply()都是用于改变函数的this指向,它们之间的区别主要在于传递参数的方式不同。在实际开发中,我们需要根据场景的需要选择不同的方法使用
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值