JavaScript call apply bind 区别
很多刚接触JavaScript的朋友,都见过call、apply、bind这三个方法,总觉得它们长得像,用起来却总踩坑,比如想给某个函数绑定this指向,结果用错了方法,直接报错或者达不到预期效果。其实这三个方法就像“给函数换身份的工具”,只是分工和用法有点不一样,今天咱们用生活化的例子拆解开,再也不会混。
先搞懂核心:函数的“this”是什么?
要区分这三个方法,得先知道一个基础:函数里的this,简单说就是“谁在调用这个函数,this就指向谁”。举个例子:你带了个小喇叭(相当于一个函数),自己拿着喊“我要喝奶茶”,那this就指向你;如果把喇叭递给闺蜜,让她喊,那this就变成闺蜜,内容还是“我要喝奶茶”,但说话的人变了——这三个方法,就是帮你把“喇叭”递给不同的人,或者固定让某个人拿着,说话的内容不变。

call和apply:临时换“说话人”,马上用一次
call和apply的功能几乎一样,都是临时改变函数的this指向,并且直接执行这个函数,区别只在于传参数的方式。
还是用小喇叭的例子:假设你有个函数是“买奶茶”,需要两个参数:奶茶口味、加不加珍珠。正常你自己调用就是买奶茶('芋泥','加珍珠'),this指向你。现在如果想让闺蜜帮你买,就用call:买奶茶.call(闺蜜, '芋泥', '加珍珠'),这里第一个参数就是要换的“说话人(this)”,后面的参数直接按顺序传,和原来的函数参数对应。
那apply呢?还是让闺蜜帮你买,用apply的话,参数得打包成一个数组:买奶茶.apply(闺蜜, ['芋泥', '加珍珠'])。简单记:call是“参数挨个给”,apply是“参数打包给数组”,就像你给朋友递东西,直接递和装在信封里递的区别。
举个实际的代码小例子,比如想让数组借用数学对象的方法求最大值:正常数组没法直接用Math.max,用call的话就是Math.max.call(null, 1,3,5),用apply就是Math.max.apply(null, [1,3,5]),结果都是5——这就是它们临时换身份干活的作用,用完就恢复原来的指向。
bind:固定“说话人”,以后再用
和前两个不一样,bind是永久改变函数的this指向,并且返回一个新函数,不会马上执行。
还是买奶茶的例子:如果闺蜜最近要帮你代买所有奶茶,不想每次都临时递喇叭,就可以用bind把“说话人”固定成闺蜜:const 闺蜜代买奶茶 = 买奶茶.bind(闺蜜)。之后不管什么时候调用闺蜜代买奶茶('抹茶','不加珍珠'),this永远是闺蜜,不用再每次传闺蜜这个参数了。
再举个开发里常见的场景:点击按钮后,需要获取当前按钮的文字。如果直接写btn.addEventListener('click', function(){ console.log(this.innerText) }),这里的this会指向btn,没问题;但如果用了箭头函数,或者要把这个函数单独抽出来,就可以用bind固定:比如const getBtnText = function(){ console.log(this.innerText) }.bind(btn),之后调用getBtnText,this永远是btn,不会因为环境变化指向别的东西。
一句话总结区别
call和apply是“临时用一次的工具,参数传法不同”;bind是“固定身份的定制工具,以后反复用”。这么记就不会混:要马上执行用call/apply,要留着以后用用bind;参数挨个给用call,打包成数组用apply。
下次再碰到需要改函数this指向的场景,先想清楚是“临时用一次”还是“以后反复用”,再选对应的方法,就不会再搞错啦。