zoukankan      html  css  js  c++  java
  • 深入理解js中的apply、call、bind

    概述

    js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向。

    apply()

    apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。

    var student = {
    	name : 'xiaoming'
    }
    function getName(firstName , lastName){
    	console.log(firstName + ' ' + this.name + ' ' + lastName)
    }
    
    getName.apply(student , ['MQ' , 'jj']); //MQ xiaoming jj
    

    call()

    call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。

    var student = {
    	name : 'xiaoming'
    }
    function getName(firstName , lastName){
    	console.log(firstName + ' ' + this.name + ' ' + lastName)
    }
    
    getName.call(student , 'MQ' , 'jj'); //MQ xiaoming jj
    

    apply(),call()常用方法

    1.数组合并

    var arr_1 = [1,2,3];
    var arr_2 = [4,5,6];
    [].push.apply(arr_1,arr_2);
    console.log(arr_1)  //[1,2,3,4,5,6]
    

    2.获取数组中的最大值和最小值

    var num_arr = [3,5,8,1,9];
    var max_num = Math.max.apply(Math , num_arr);
    var min_num = Math.min.call(Math , 3 , 5 , 8 , 1 , 9)
    console.log(max_num) //9
    console.log(min_num) //1
    

    3.类(伪)数组使用数组方法

    var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
    

    bind()方法

    bind()方法与call(),apply()类试,也可改变函数体内的this指向。

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

    var foo = {
        bar : 1,
        eventBind: function(){
            var _this = this;
            $('.someClass').on('click',function(event) {
                /* Act on the event */
                console.log(_this.bar);     //1
            });
        }
    }
    

    使用bind解决保存this的问题

    var foo = {
        bar : 1,
        eventBind: function(){
            $('.someClass').on('click',function(event) {
                /* Act on the event */
                console.log(this.bar);      //1
            }.bind(this));
        }
    }
    

     bind参数的使用:

    var student = {
    	name : 'xiaoming'
    }
    
    function getName(firstName , lastName){
    	console.log(firstName + ' ' + this.name + ' ' + lastName)
    }
    
    var getBindName = getName.bind(student,'lihui');
    getName('Mrs','jj'); //Mrs  jj
    getBindName(); //lihui xiaoming undefined
    getBindName('jj'); //lihui xiaoming jj
    getBindName('Mrs','jj'); //lihui xiaoming Mrs
    getName.call(student,'lihui') //lihui xiaoming undefined
    

     call 是把第二个及以后的参数作为 getName方法的实参传进去,而 getBindName方法的实参实则是在 bind 中参数的基础上再往后排。

     apply、call、bind三者之间的比较

    var student = {
    	age : 18
    }
    var studentInfo = {
    	getAge () {
    		return this.age
    	}
    }
    console.log(studentInfo.getAge.bind(student)()); //18
    console.log(studentInfo.getAge.call(student)); //18
    console.log(studentInfo.getAge.apply(student)); //18
    

     apply/call在改变函数上下文环境之后, 会立即执行函数。而bind()不会立即执行,而是返回一个改变了上下文 this 后的函数。

    总结

    • apply 、 call 、bind 三者都是用来改变函数的this对象的指向
    • apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文
    • apply 、 call 、bind 三者都可以利用后续参数传参,只是方式不同
    • apply , call改变函数上下文之后会立即调用,而bind会返回一个改变了this的函数,以便以后调用

    参考资料

    1.【优雅代码】深入浅出 妙用javascript的call , apply , bind

    2.javascript中的call , apply详解

      

  • 相关阅读:
    hdu4405Aeroplane chess 概率dp水题
    【基础算法】排序-复杂排序之二(找出第K大的数)
    java代码实现输出指定以.java结尾的文件的绝对路径
    算法 Heap sort
    hdu2141Can you find it?
    c/c++:回调函数
    怎样在编译的时候,控制删除apk不用的资源?
    javascript原型的改动与重写(覆盖)区别
    深入理解Tomcat虚拟文件夹
    C++设计模式之代理模式
  • 原文地址:https://www.cnblogs.com/helloluo/p/7474764.html
Copyright © 2011-2022 走看看