js的call,apply,bind的使用与区别

在原生js中会有三个很常见的函数,call,apply,bind

他们的作用就是改变当前函数的this指针,

但是细微来说他们还是有不同的。

1)call,apply都是执行某一函数,发现this有变得时候才使用的(进行时)

2)bind是在函数进行调用之前,就强行给变了this的指向(进行前),它的效果是返回一个函数(只是给变了this指向)

说的很多了,不说了

demo :

    function Foo(name){
        this.name=name;
    }

    Foo.prototype.getName=function(){
        return this.name;
    }

    function Bar(name,label){
        Foo.call(this,name);
        this.label=label;
    }

    Bar.prototype.getMylabel=function(){
            return this.label;
    }

    var fo=new Foo('一灯');
      console.log(fo.getName());  //一灯

    var ba=new Bar("是你的?","大家的");
     console.log( ba.getMylabel());    //大家的

console.log(ba);//bar{label:大家的,name:是你的?}

明白人都会有个问题,这个ba怎么将name值赋值成功的,因为他没有Foo方法呀?

这就是call的厉害了。慢慢体会其中奥秒,

一个问题怎么把call换成apply???

只需要这样: Foo.call(this,name);要被改变成--->Foo.apply(this,[name]).....多说一句,applay与call的却别就是applay的参数是一个数组,

第二个问题:怎么换成bind呢????

已经说过bind的使用是函数进行前进行操作的,返回一个函数

 var setName=Foo.bind(this);

 setName(name); 

当然也可以写成一句话:Foo.bind(this)(name);表面上来看,好像只是与call多了一个括号,但是含义确实不同,bind是先返回一个函数,然后执行函数,,,,,,


第三个问题:我要怎么输出我的ba中的name呢???

很简单呀:console.log(ba.getName());

嗯,错了,确实错了,ba没有getName()方法呀。

怎么办了,这里

方法不唯一.

第一种方法:

console.log(Foo.prototype.getName.call(ba));

或者  console.log(Foo.prototype.getName.bind(ba)());

 console.log(Foo.prototype.getName.apply(ba));

 第二种方法:

Bar.prototype=Object.create(Foo.prototype);

console.log(ba.getName());//是你的?

【Objecrt.create的作用就是将Foo.prototype与Bar.prototype相关联起来】

console.log(ba.getMylable());//error       出错了什么鬼???????

【忘记说了,Object.create()他会出创建一个新对象,这样Bar.prototype就会被替换了,这样就尴尬了,getMylabel()就丢了。。。。。。。】

聪明的孩纸说:那么就这样来:

  Bar.prototype=Object.create(Foo.prototype);
  Bar.prototype.getMylabel=function(){
       return this.label;
  }

一点毛病也没用,很好。

其实能更高雅点,当你翻开你的课本,你就会发现其实,Object.setPrototypeOf(Bar.prototype,Foo.Prototype)即可规避上面的尴尬现象了,

Object.setPrototypeOf(Bar.prototype,Foo.Prototype)会改变前者的一些东西,不会将他抛弃

到这里我已经没什么好说的,只想说,bind函数具有一定的兼容性问题

原文地址:https://www.cnblogs.com/evaling/p/7396253.html