Javascript中apply、call、bind

Javascript中apply、call、bind

一、call 方法

调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容)。

语法

call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

参数说明

thisObj :可选项。将被用作当前对象的对象。
arg1, arg2,   , argN :可选项。将被传递方法参数序列。

备注

call 方法可以用来代替另一个对象调用一个方法。

call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

实例

  •  
  •  
  • HTML 代码   复制
  • 
    <input type="text" id="myText"    value="input text">
    <script>
        function Obj(){this.value="对象!";}
        var value="global 变量";
        function Fun1(){alert(this.value);}
    
         window.Fun1();   //global 变量
         Fun1.call(window);  //global 变量
         Fun1.call(document.getElementById('myText'));  //input text
         Fun1.call(new Obj());   //对象!
    </script>
    
    		

  •  

  • JScript 代码   复制
  • 
    var first_object = { 
       num: 42 
    }; 
    var second_object = { 
       num: 24 
    }; 
    function multiply(mult) { 
       return this.num * mult; 
    } 
    multiply.call(first_object, 5); // returns 42 * 5 
    multiply.call(second_object, 5); // returns 24 * 5 
    
    		
  • 二、apply方法

    对于apply和call两者在作用上是相同的,但两者在参数上有区别的。

    三、apply、call 的区别

    1、对于第一个参数意义都一样,但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。

    func.call(func1,var1,var2,var3) 对应的apply写法为:func.apply(func1,[var1,var2,var3])

    例如

  •  
  •  
  • JScript 代码   复制
  • 
        var func=new function(){this.a="func"}
        var myfunc=function(x,y){
            var a="myfunc";
             alert(this.a);
             alert(x + y);
        }
        myfunc.call(func,"var"," fun");// "func" "var fun"
        myfunc.apply(func,["var"," fun"]);// "func" "var fun"
    
    		
  • 2、当你的参数是明确知道数量时用 call ,而不确定的时候用 apply,然后把参数 push 进数组传递进去。

    3、通过实例说明两者的区别

  •  
  •  
  • JScript 代码   复制
  • 
    //1、数组之间追加
    
    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] */
    
    
    
    //2、获取数组中的最大值和最小值
    
    
    var  numbers = [5, 458 , 120 , -215 ];  
    
    var maxInNumbers = Math.max.apply(Math, numbers),   //458
    
        maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
    
    		
  • 4、Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
    但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。

    四、bind方法

    bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。

    例如

  •  
  • JScript 代码   复制
  • 
    
    var foo = {
    
        bar : 1,
    
        eventBind: function(){
    
            $('.someClass').on('click',function(event) {
    
                /* Act on the event */
    
                console.log(this.bar);      //1
    
            }.bind(this));
    
        }
    
    }
    
    		
  • 在上述代码里,bind() 创建了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。因此,这里我们传入想要的上下文 this(其实就是 foo ),到 bind() 函数中。然后,当回调函数被执行的时候, this 便指向 foo 对象。 

    又如:

  •  
  • JScript 代码   复制
  • 
    
    var bar = function(){
    
    console.log(this.x);
    
    }
    
    var foo = {
    
    x:3
    
    }
    
    bar(); // undefined
    
    var func = bar.bind(foo);
    
    func(); // 3
    
    		
  • 这里我们创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。

    五、apply、call、bind比较

    1、三者都是用来改变函数的this对象的指向的;

    2、三者第一个参数都是this要指向的对象,也就是想指定的上下文;

    3、三者都可以利用后续参数传参;

    4、bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

    5、当希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。

    例如

  •  
  • JScript 代码   复制
  • 
    
    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
    
    		
  • 标签: