Javascript Function.prototype.bind詳細(xì)分析
Function.prototype.bind分析
bind()方法會(huì)創(chuàng)建一個(gè)新的函數(shù),成為綁定函數(shù)。當(dāng)調(diào)用這個(gè)綁定函數(shù)時(shí),綁定函數(shù)會(huì)以創(chuàng)建它時(shí)傳入的第一個(gè)參數(shù)作為this,傳入bind()方法的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)取原函數(shù)。
實(shí)際使用中我們經(jīng)常會(huì)碰到這樣的問題:
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
這個(gè)時(shí)候輸出this.name是pig,原因是this的指向是在運(yùn)行函數(shù)時(shí)確定的,而不是在定義函數(shù)時(shí)確定的,再因?yàn)閟etTimeout是在全局環(huán)境下只想,所以this就指向了window。
以前解決這個(gè)問題的辦法通常是緩存this,例如:
var name = "pig"; function Person(name){ this.name = name; this.getName = function(){ //在這里緩存一個(gè)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)旗
這樣就解決了這個(gè)問題,非常方便,因?yàn)樗沟胹etTimeout函數(shù)中可以訪問Person的上下文。
現(xiàn)在有一個(gè)更好的解決辦法,可以使用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)建一個(gè)函數(shù),使得這個(gè)函數(shù)無論怎么樣調(diào)用都擁有同樣的this值。JavaScript新手經(jīng)常犯的一個(gè)錯(cuò)誤就是將一個(gè)方法從一個(gè)對象中拿出來,然后再調(diào)用,希望方法中的this是原來的對象(比如在回調(diào)函數(shù)中傳入這個(gè)方法)。如果不做特殊處理的話,一般會(huì)丟失原來的對象。從原來的函數(shù)和原來的對象創(chuàng)建一個(gè)綁定函數(shù),則可以很漂亮的解決這個(gè)問題:
//定義全局變量x var x = "window"; //在module內(nèi)部定義x var module = { x:"module", getX:function(){ console.log(this.x); } } module.getX(); //返回module,因?yàn)樵趍odule內(nèi)部調(diào)用getX() var getX = module.getX; getX(); //返回window,因?yàn)檫@個(gè)getX()是在全局作用域中調(diào)用的 //綁定getX()并將this值設(shè)為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及以下版本中不被支持,所以如果沒有一個(gè)備選方案的話,可能會(huì)在運(yùn)行時(shí)出現(xiàn)問題。bind函數(shù)在ECMA-262第五版才被加入。它可能不無法在所有瀏覽器上運(yùn)行。你可以在腳本部分加入如下代碼,讓不支持的瀏覽器也能使用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,當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的this指向,當(dāng)使用new操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效。
arg1, arg2, …,當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)加上綁定函數(shù)本身的參數(shù)會(huì)按照順序作為原函數(shù)運(yùn)行時(shí)的參數(shù)。
描述
bind()函數(shù)會(huì)創(chuàng)建一個(gè)新的函數(shù)(一個(gè)綁定的函數(shù))有同樣的函數(shù)體(在ECMAScript 5 規(guī)范內(nèi)置Call屬性),當(dāng)該函數(shù)(綁定函數(shù)的原函數(shù))被調(diào)用時(shí)this值綁定到bind()的第一個(gè)參數(shù),該參數(shù)不能被重寫。綁定函數(shù)被調(diào)用時(shí),bind()也接受預(yù)設(shè)的參數(shù)提供給原函數(shù)。一個(gè)綁定函數(shù)也能使用new操作符創(chuàng)建對象:這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。提供的this值被忽略,同事調(diào)用的參數(shù)被提供給模擬函數(shù)。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析
- jquery中l(wèi)ive()方法和bind()方法區(qū)別分析
- C#中DataBindings用法實(shí)例分析
- jQuery中trigger()與bind()用法分析
- Android4.1中BinderService用法實(shí)例分析
- JQuery中Bind()事件用法分析
- javascript中call,apply,bind的用法對比分析
- PHP PDOStatement:bindParam插入數(shù)據(jù)錯(cuò)誤問題分析
- jQuery中的.bind()、.live()和.delegate()之間區(qū)別分析
- js apply/call/caller/callee/bind使用方法與區(qū)別分析
- JS類庫Bindows1.3中的內(nèi)存釋放方式分析
相關(guān)文章
關(guān)于ES6中的箭頭函數(shù)超詳細(xì)梳理
箭頭函數(shù)可以說是es6的一大亮點(diǎn),使用箭頭函數(shù),可以簡化編碼過程,是代碼更加的簡潔,下面這篇文章主要給大家介紹了關(guān)于ES6中箭頭函數(shù)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08IE下雙擊checkbox反應(yīng)延遲問題的解決方法
這篇文章主要介紹了IE下雙擊checkbox反應(yīng)延遲問題的解決方法,需要的朋友可以參考下2014-03-03JavaScript代碼實(shí)現(xiàn)左右上下自動(dòng)晃動(dòng)自動(dòng)移動(dòng)
最近幾天做了一個(gè)項(xiàng)目,原來是用css3動(dòng)畫做的,由于不兼容IE,改成用js做了,特此分享給大家,供大家參考2016-04-04小程序websocket心跳庫(websocket-heartbeat-miniprogram)
這篇文章主要介紹了小程序websocket心跳庫(websocket-heartbeat-miniprogram),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02