JavaScript中apply bind call的异同(重点讲解call方法)

JavaScript中若想改变this的指向那就必须用到apply call bind 方法,但其中三个方法有他们的区别

 apply()

apply():第一个参数将代替function类里的this对象,第二个参数是数组,将他作为参数传给function的arguments
function a(){
       this.name = 'a';
        this.show = function(){alert(this.name)};
    }
    function b() {
        this.name = 'b';
    }
    var B = new b();
    a.apply(B);
    B.show();
    这时输出a,这是因为apply方法中将this的指针改为了b,在functionb.name = 'a', b.show = function(){alert(this.name)};所以当再次调用B.show()时输出的是a

 function A(a,b) {
        this.a = a;
        this.b = b;
    }
    function B() {
        A.apply(this,[1,2]);
        this.c = 3;
    }
    var s = new B();
    alert(s.a+","+s.b+","+s.c);
    这时输出123,这是因为在B函数中用apply方法将B的this给了a的this,将后面的12作为参数传给了A,这时给B的this分别添加了a和b属性,所以再次输出的时候B中会存在a,b,c三种属性。

 call ()

call():call方法和apply方法类似只不过传入参数方法不同call方法中第二个参数不是数组,而是从第二个开始其余参数直接传给函数的arguments
,f  function a(){
        this.name = 'a';
        this.show = function(){alert(this.name)};
    }
    function b() {
        this.name = 'b';
    }
    var B = new b();
    a.call(B);
    B.show();
    在这里我们将之前的apply方法改为了call方法,执行之后的结果和方法与apply方法相同

    function A(a,b) {
        this.a = a;
        this.b = b;
    }
    function B() {
        A.call(this,1,2);
        this.c = 3;
    }
    var s = new B();
    alert(s.a+","+s.b+","+s.c);
    在这里我们将B函数中的apply方法改为了call方法,执行之后的结果和方法与apply方法相同,但是在这里call方法传入的参数发生了变化,apply是传入数组,而call方法是直接将参数传入

有了之前的铺垫,那么我们现在继续深入一下
    function A(a,b) {
        this.a = a;
        this.b = b;
    }
    function B() {
        this.a = 5;
        this.c = 3;
        A.call(this,1,2);
    }
    var s = new B();
    alert(s.a+","+s.b+","+s.c);
    这时大家猜测一下输出是什么,是523吗?
    不,这时继续输出123,为什么呢?这时因为给B调用了A的call方法,使A的this指针指向了B,虽然我们定义了B的a为5,但是在调用call方法之后又将B的a重写为了1

    function A(){
        this.show = function(){alert(this.name)}
    }
    function B(){
        this.name = 'b';
    }
    var C = new A();
    var D = new B();
    C.show.call(D);//b
    alert(D.show);//undefined
    这段代码中,让C.show中的this指向了D,但是并没有给D写入C.show,所以第一个输出b第二个输出undefined

    最后我们来看一种奇怪的调用方式
    function A(a){
        alert(this+","+a+","+'A');
    }
    function B(b){

        alert(this+","+b+","+'B');
    }
    var C = A.call;
    A('a');
    C.call(B,'a');
    大家看到这估计已经懵逼了吧,想不到还可以这么调用吧
    在这里第一个alert输出[object Window],a,A,结果正常,第二个alert输出a,undefined,A,这时就有人会问了,为什么a做了this指针而应该输出a的地方却输出了undefined
    我们先来看一下调用一次call方法输出什么
    function A(a){
        alert(this+","+a+","+'A');
    }
    function B(b){
        alert(this+","+b+","+'B');
    }
    var C = A;
    A('a');//[object Window],a,A
    C.call(B,'a');// function B(b){alert(this+","+b+","+'B');},a,A
    也就是说调用一次call方法是没问题的而且将他的this指向了B
    那么在调用两次call方法时A的this指针域指向了arguments的第一个参数,而后面的参数则是作为了arguments的参数。

 bind()

bind():这个方法会创建一个函数的实例,传入参数与call方法相同
var name = 'global';
    function person () {
       this.name = 'hero';
    }
    // 输出姓名、年龄和职业
    function print(age, job) {
        console.log(this.name, age, job);
    }
    var Person = new person();
    var printf = print.bind(Person);
    printf(18, '前端工程师');
    在这里将print通过bind方法将this的指针改为了print,返回了一个函数,调用函数并传入参数
    输出hero 20 前端工程师

    但是对bind方法new会让bind方法绑定的第一个参数消失

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }

    var _Person = Person.bind(null, 'hanzichi');
    var p = new _Person(30); // Person {name: "hanzichi", age: 30}
    因为new方法导致bind第一个参数无效
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章