学习笔记: apply、call、bind的使用

文章背景:学习前端半年后,掌握基本的vue以及其组件使用,并使用vue2.0完成两个项目的开发(一个是类似办公系统,包括权限、审批、图片展示、echarts、canvas等;一个是app项目,纯展示功能,交互特别少,html5完成);但是JavaScript开始渐渐遗忘,本文主要目的加深前面学习的js的一些知识,主要是不常用,被忘记了。

先看一个函数——————bind部分

function mineFun(name, age) {   

            console.log(name, age, this);

        };

        mineFun('张三', '33');

你觉得会输出什么?

mineFun('张三', '33');//不用想,看过js基础的都知道,输出   

 此时this 的指向是,window;

接着上面这个函数继续,

mineFun.bind(text, '张三', '33');

你觉得会输出什么?

mineFun.bind(text, '张三', '33');//  输出如下:

 哈哈哈,啥也没有,再来看,

 bind方法生成的是一个新的方法,需要调用这个方法才能正常运行;

打印结果:

 有什么区别?  除了最后一个结果,其他都一样,此时this的指向并不是window,而是这个名叫text 的变量,本质是个字符串;

同理,把text换成obj,在新的函数中,this 的指向会再次改变

 

 再继续看这个函数,————————apply部分

 

 apply属性,也是改变this的指向,这一点与bind一致,区别就是,它不需要再次调用这个方法,其次它的参数必须是一个数组形式,否则就会报错:

  再继续看这个函数,————————call部分

 

 call这个属性,就更简单了,不需要再次调用,传的值也是正常的,是什么就是什么,不需要像apply一样要改成数组。

看到这里,我那个时候反正是懵逼的,什么玩意?这三个属性不基本一样嘛?为什么大佬们对这些属性都表示一定要明白,一定要懂,一定要会用。

别急,咱们看看几个实例,你可能会有些启发。等到后面遇到了,很有可能会打通你的任督二脉,忽然一下就明白了;

// 实例1,一看就懂

function ClassA(name, age, sex) {

            this.name = name;

            this.age = age;

            this.sex = sex;

            // 介绍自己

            this.information = function information() {

                console.log(this.name + '今年' + this.age + ' 性别:' + this.sex)

            }

            // 介绍工作

            this.work = function work(workName, workName2, workName3) {

                console.log(this.name + '是做:' + workName + ',' + workName2 + ',' + workName3)

            }

        };       

 function ClassB(name, age, sex) {

            this.name = name;

            this.age = age;

            this.sex = sex;

            // 推算年纪

            this.ageAdd = function ageAdd() {

                console.log(this.name + '10年后' + (10 + Number(this.age)) + '岁');

            }

        };

        let a = new ClassA('张三', '33', '男');

        a.information();//张三今年33 性别:男

        let b = new ClassB('大妹子', '20', '女');

        b.ageAdd();//张三10年后43岁

上面提供两个函数(类),都可以正常使用。

        // 现在我想要让 这个 大妹子 介绍一下自己(就是像ClassA中的方法information),应该怎么做?

        //没学call、apply、bind之前,我肯定会说,在ClassB中加一个跟ClassA一模一样的方法就行

        //思考:你这个方法是永久性的还是临时性的,如果是临时性的,你自己再去写一个方法不是会很累赘嘛,

        //如果是永久性的,无所谓,随你方便,都可以的

        思考完看下面的方法:

        // 用bind方法完成;

        a.information.bind(b)();//大妹子今年20 性别:女

        //用apply方法完成:

        a.information.apply(b);//大妹子今年20 性别:女

        // 用call方法完成

        a.information.call(b);//大妹子今年20 性别:女

        //上面好像apply  与  call  没啥区别,继续看,另一个方法 work;

        a.work(); //张三是做:undefined,undefined,undefined

        a.work.bind(b, '司机', '裁缝', '程序员')();//大妹子是做:司机,裁缝,程序员

        a.work.apply(b, ['司机', '裁缝', '程序员']);//大妹子是做:司机,裁缝,程序员,这里参数必须是数组

        a.work.call(b, '司机', '裁缝', '程序员');//大妹子是做:司机,裁缝,程序员

        //这下看的明白不?  最上面的information 方法,使用的参数是类本身自带的参数,全部被存在了ClassA内部,可以通过this直接调用

        //下面的work,引用的参数需要你自己传入, 可以清晰的看到call bind apply 的传参区别;

        // 再看实例:   有关bind的传参问题

        // 现在有一个LOL英雄简介,需要根据不同的武器类型,执行不同的清兵方法

        function ClassC(type, name) {

            if (type == '剑') {

                console.log(name + '用' + type + '戳死了小兵');

            } else if (type == '法杖') {

                console.log(name + '用' + type + '唱死了小兵');

            } else if (type == '刀') {

                console.log(name + '用' + type + '砍死了小兵');

            }

        };

        ClassC('刀', '蛮族之王');//蛮族之王用刀砍死了小兵

        ClassC('法杖', '死歌');//死歌用法杖唱死了小兵

        ClassC('剑', '无双剑姬');//无双剑姬用剑戳死了小兵

        // 现在有人帮你把英雄人物根据武器分好类了,你只负责输出用剑的就行,你应该怎么做?

        let useKnife = ClassC.bind(this, '刀');

        useKnife('男刀');//男刀用刀砍死了小兵

        useKnife('女刀');//女刀用刀砍死了小兵

        你只需要将第一个参数固定,然后,在你需要调用时候,再次传入剩余参数就可以,是不是很方便了?不需要你每次都输入这个 武器类型

        //总结:

        //1.bind  可以让你在需要调用方法的时候再掉用,不会立即执行,同时它可以改变this的指向,并且会将它第二个参数及后面的参数传入这个对象中,以供使用(a.work.bind(b, '司机', '裁缝', '程序员')() 这样的形式)

        //        但是,你在bind的时候,如果定义了一个参数,那么它会将这个参数默认设置为第一个参数,其他参数会被在调用的时候,往后继续排列(相当于第二个参数被你定义并占用)

        2. apply  劫持一个对象的方法,继承一个对象的属性,这个实例太多了,比如让你去查看一个数组里面最大的值,你怎么干?for循环遍历比较?NONONO,太繁琐了,用apply方法一下搞定

 骚不骚?好不好用?你有你想不到!!(有没有它干不了的我也不敢乱说,hhh)

3. call就不再多说,改变this指向,顺序传入对应参数(区别于apply),立即执行(区别于 bind)

任何问题请留言, 工作日全天在线,欢迎互相探讨前端知识。


版权声明:本文为weixin_53399156原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。