js的call,apply,bind的使用與區別

在原生js中會有三個很常見的函數,call,apply,bind數組

他們的做用就是改變當前函數的this指針,app

可是細微來講他們仍是有不一樣的。函數

1)call,apply都是執行某一函數,發現this有變得時候才使用的(進行時)this

2)bind是在函數進行調用以前,就強行給變了this的指向(進行前),它的效果是返回一個函數(只是給變了this指向)spa

說的不少了,不說了prototype

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方法呀?code

這就是call的厲害了。慢慢體會其中奧秒,對象

 

一個問題怎麼把call換成apply???blog

只須要這樣: 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函數具備必定的兼容性問題

相關文章
相關標籤/搜索