js中的改变this指向的apply、call和bind的区别和使用

来源:程序思维浏览:2769次
在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢。

js中的改变this指向的apply、call和bind的区别和使用

在说区别之前还是先总结一下三者的相似之处:

1、都是用来改变函数的this对象的指向的。
2、第一个参数都是this要指向的对象。
3、都可以利用后续参数传参。

代码案例展示:

call示例展示:

var obj1={
        name:"李四",
        person:function (args) {
            console.log(this.name,args);
        }
    };
    var obj2={
        name:"张三",
        person:function () {
            console.log(this.name);
        }
    };
    obj1.person.call(obj2, "传参");

apply示例展示:

var obj1={
        name:"李四",
        person:function () {
            console.log(Array.prototype.slice.apply(arguments));//arguments转真实数组
            //console.log(this.name,args);
        },
        person2:function (...args) {//es6接收参数
            console.log(args);
            //console.log(this.name,args);
        }
    };
    var obj2={
        name:"张三",
        person:function () {
            console.log(this.name);
        }
    };
    obj1.person.apply(obj2, ['参数1','参数2']);
    obj1.person2.apply(obj2, ['参数1','参数2']);

bind示例展示:

var obj1={
        name:"李四",
        person:function (args) {
            console.log(this.name,args);
        }
    };
    var obj2={
        name:"张三",
        person:function () {
            console.log(this.name);
        }
    };
    //第一种调用方法
    var fnPerson=obj1.person.bind(obj2, "传参");
    fnPerson();

    //第二种调用方法
    obj1.person.bind(obj2, "传参")();

好了例子很简单但是基本的使用方法跟场景都涉及到了。

call跟apply的用法几乎一样,唯一的不同就是传递的参数不同,call只能一个参数一个参数的传入。
apply则只支持传入一个数组,哪怕是一个参数也要是数组形式。最终调用函数时候这个数组会拆成一个个参数分别传入。
至于bind方法,他是直接改变这个函数的this指向并且返回一个新的函数,之后再次调用这个函数的时候this都是指向bind绑定的第一个参数。bind传参方式跟call方法一致。

由于apply函数传参的特殊性,我们又衍生出了一个黑魔法。

如果一个数组我们已知里面全都是数字,想要知道最大的那个数,由于Array没有max方法,Math对象上有
我们可以根据apply传递参数的特性将这个数组当成参数传入
最终Math.max函数调用的时候会将apply的数组里面的参数一个一个传入,恰好符合Math.max的参数传递方式
这样变相的实现了数组的max方法。min方法也同理

const arr = [1,2,3,4,5,6]
const max = Math.max.apply(null, arr)
console.log(max)    // 6

这里bind函数也有一个小技巧

如果你想将某个函数绑定新的`this`指向并且固定先传入几个变量可以在绑定的时候就传入,之后调用新函数传入的参数都会排在之后

const obj = {}
function test(...args) {console.log(args)}
const newFn = test.bind(obj, '静态参数1', '静态参数2')
newFn('动态参数3', '动态参数4')

这里bind函数也有一个小技巧

总结:
  1. 当我们使用一个函数需要改变this指向的时候才会用到call、apply、bind
  2. 如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 ...)
  3. 如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 ...])
  4. 如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2...)
精品好课
HTML5基础入门视频教程易学必会
HTML5基础入门视频教程,教学思路清晰,简单易学必会。适合人群:创业者,只要会打字,对互联网编程感兴趣都可以学。课程概述:该课程主要讲解HTML(学习HTML5的必备基础语言)、CSS3、Javascript(学习...
React实战视频教程仿京东移动端电商
React是前端最火的框架之一,就业薪资很高,本课程教您如何快速学会React并应用到实战,对正在工作当中或打算学习React高薪就业的你来说,那么这门课程便是你手中的葵花宝典。
jQuery视频教程从入门到精通
jquery视频教程从入门到精通,课程主要包含:jquery选择器、jquery事件、jquery文档操作、动画、Ajax、jquery插件的制作、jquery下拉无限加载插件的制作等等......
Vue2+Vue3+ES6+TS+Uni-app开发微信小程序从入门到实战视频教程
2021年最新Vue2+Vue3+ES6+TypeScript和uni-app开发微信小程序从入门到实战视频教程,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己...
最新完整React视频教程从入门到精通纯干货纯实战
React是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习React高薪就...
VUE2+VUE3视频教程从入门到精通(全网最全的Vue课程)
VUE是目前最火的前端框架之一,就业薪资很高,本课程教您如何快速学会VUE+ES6并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习VUE高薪就...
HTML5视频播放器video开发教程
适用人群1、有html基础2、有css基础3、有javascript基础课程概述手把手教你如何开发属于自己的HTML5视频播放器,利用mp4转成m3u8格式的视频,并在移动端和PC端进行播放支持m3u8直播格式,兼容...
最新完整React+VUE视频教程从入门到精,企业级实战项目
React和VUE是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React和VUE并应用到实战,教你如何解决内存泄漏,常用库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习Re...
收藏
扫一扫关注我们