在原生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函數具備必定的兼容性問題