Javascript Function.prototype.bind詳細分析
Function.prototype.bind分析
bind()方法會創(chuàng)建一個新的函數(shù),成為綁定函數(shù)。當調用這個綁定函數(shù)時,綁定函數(shù)會以創(chuàng)建它時傳入的第一個參數(shù)作為this,傳入bind()方法的第二個以及以后的參數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調取原函數(shù)。
實際使用中我們經常會碰到這樣的問題:
var name = "pig";
function Person(name){
this.name = name;
this.getName = function(){
setTimeout(function(){
console.log("Hello,my name is "+this.name);
},100);
}
}
var weiqi = new Person("衛(wèi)旗");
weiqi.getName();
//Hello,my name is pig
這個時候輸出this.name是pig,原因是this的指向是在運行函數(shù)時確定的,而不是在定義函數(shù)時確定的,再因為setTimeout是在全局環(huán)境下只想,所以this就指向了window。
以前解決這個問題的辦法通常是緩存this,例如:
var name = "pig";
function Person(name){
this.name = name;
this.getName = function(){
//在這里緩存一個this
var self = this;
setTimeout(function(){
//在這里是有緩存this的self
console.log("Hello,my name is "+self.name);
},100);
}
}
var weiqi = new Person("衛(wèi)旗");
weiqi.getName();
//Hello,my name is 衛(wèi)旗
這樣就解決了這個問題,非常方便,因為它使得setTimeout函數(shù)中可以訪問Person的上下文。
現(xiàn)在有一個更好的解決辦法,可以使用bind()函數(shù),上面的例子可以被更新為:
var name = "pig";
function Person(name){
this.name = name;
this.getName = function(){
setTimeout(function(){
console.log("Hello,my name is "+this.name);
}.bind(this),100);
//注意上面這一行,添加了bind(this)
}
}
var weiqi = new Person("衛(wèi)旗");
weiqi.getName();
//Hello,my name is 衛(wèi)旗
bind()最簡單的用法是創(chuàng)建一個函數(shù),使得這個函數(shù)無論怎么樣調用都擁有同樣的this值。JavaScript新手經常犯的一個錯誤就是將一個方法從一個對象中拿出來,然后再調用,希望方法中的this是原來的對象(比如在回調函數(shù)中傳入這個方法)。如果不做特殊處理的話,一般會丟失原來的對象。從原來的函數(shù)和原來的對象創(chuàng)建一個綁定函數(shù),則可以很漂亮的解決這個問題:
//定義全局變量x
var x = "window";
//在module內部定義x
var module = {
x:"module",
getX:function(){
console.log(this.x);
}
}
module.getX();
//返回module,因為在module內部調用getX()
var getX = module.getX;
getX();
//返回window,因為這個getX()是在全局作用域中調用的
//綁定getX()并將this值設為module
var boundGetX = getX.bind(module);
boundGetX();
//返回module,綁定以后this值始終為module
瀏覽器支持情況:
| Browser | Version support |
|---|---|
| Chrome | 7 |
| FireFox(Gecko) | 4.0(2) |
| Internet Explorer | 9 |
| Opera | 11.60 |
| Safari | 5.14 |
很不幸,F(xiàn)unction.prototype.bind在IE8及以下版本中不被支持,所以如果沒有一個備選方案的話,可能會在運行時出現(xiàn)問題。bind函數(shù)在ECMA-262第五版才被加入。它可能不無法在所有瀏覽器上運行。你可以在腳本部分加入如下代碼,讓不支持的瀏覽器也能使用bind()功能。
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
語法
fun.bind(thisArg[, arg1[, arg2[, …]]])
參數(shù)
thisArg,當綁定函數(shù)被調用時,該參數(shù)會作為原函數(shù)運行時的this指向,當使用new操作符調用綁定函數(shù)時,該參數(shù)無效。
arg1, arg2, …,當綁定函數(shù)被調用時,這些參數(shù)加上綁定函數(shù)本身的參數(shù)會按照順序作為原函數(shù)運行時的參數(shù)。
描述
bind()函數(shù)會創(chuàng)建一個新的函數(shù)(一個綁定的函數(shù))有同樣的函數(shù)體(在ECMAScript 5 規(guī)范內置Call屬性),當該函數(shù)(綁定函數(shù)的原函數(shù))被調用時this值綁定到bind()的第一個參數(shù),該參數(shù)不能被重寫。綁定函數(shù)被調用時,bind()也接受預設的參數(shù)提供給原函數(shù)。一個綁定函數(shù)也能使用new操作符創(chuàng)建對象:這種行為就像把原函數(shù)當成構造器。提供的this值被忽略,同事調用的參數(shù)被提供給模擬函數(shù)。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Android系統(tǒng)進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
- jquery中l(wèi)ive()方法和bind()方法區(qū)別分析
- C#中DataBindings用法實例分析
- jQuery中trigger()與bind()用法分析
- Android4.1中BinderService用法實例分析
- JQuery中Bind()事件用法分析
- javascript中call,apply,bind的用法對比分析
- PHP PDOStatement:bindParam插入數(shù)據(jù)錯誤問題分析
- jQuery中的.bind()、.live()和.delegate()之間區(qū)別分析
- js apply/call/caller/callee/bind使用方法與區(qū)別分析
- JS類庫Bindows1.3中的內存釋放方式分析
相關文章
JavaScript代碼實現(xiàn)左右上下自動晃動自動移動
最近幾天做了一個項目,原來是用css3動畫做的,由于不兼容IE,改成用js做了,特此分享給大家,供大家參考2016-04-04
小程序websocket心跳庫(websocket-heartbeat-miniprogram)
這篇文章主要介紹了小程序websocket心跳庫(websocket-heartbeat-miniprogram),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02

