深入理解JS中的Function.prototype.bind()方法
前言
對(duì)于函數(shù)綁定(Function binding)很有可能是大家在使用JavaScript時(shí)最少關(guān)注的一點(diǎn),但是當(dāng)你意識(shí)到你需要一個(gè)解決方案來(lái)解決如何在另一個(gè)函數(shù)中保持this上下文的時(shí)候,你真正需要的其實(shí)就是 Function.prototype.bind()
,只是你有可能仍然沒(méi)有意識(shí)到這點(diǎn)。
第一次遇到這個(gè)問(wèn)題的時(shí)候,你可能傾向于將this設(shè)置到一個(gè)變量上,這樣你可以在改變了上下文之后繼續(xù)引用到它。
一. bind的語(yǔ)法
bind()
方法的主要作用就是將函數(shù)綁定至某個(gè)對(duì)象,bind()
方法會(huì)創(chuàng)建一個(gè)函數(shù),函數(shù)體內(nèi)this對(duì)象的值會(huì)被綁定到傳入bind()
函數(shù)的值。
1.1 定義
bind()的定義如下:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
bind() 函數(shù)會(huì)創(chuàng)建一個(gè)新函數(shù)(稱為綁定函數(shù)),新函數(shù)與被調(diào)函數(shù)(綁定函數(shù)的目標(biāo)函數(shù))具有相同的函數(shù)體。當(dāng)目標(biāo)函數(shù)被調(diào)用時(shí) this 值綁定到 bind()
的第一個(gè)參數(shù),該參數(shù)不能被重寫(xiě)。
1.2 原理
可以用如下代碼模擬bind()
的原理:
Function.prototype.bind = function(context) { var self = this; // 保存原函數(shù) return function() { // 返回一個(gè)新函數(shù) return self.apply(context, arguments); // 執(zhí)行新函數(shù)時(shí),將傳入的上下文context作為新函數(shù)的this } }
1.3 語(yǔ)法
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
二. bind的應(yīng)用場(chǎng)景
2.1 實(shí)現(xiàn)對(duì)象繼承
var A = function(name) { this.name = name; } var B = function() { A.bind(this, arguments); } B.prototype.getName = function() { return this.name; } var b = new B("hello"); console.log(b.getName()); // "hello"
2.2 事件處理
var paint = { color: "red", count: 0, updateCount: function() { this.count++; console.log(this.count); } }; // 事件處理函數(shù)綁定的錯(cuò)誤方法: document.querySelector('button') .addEventListener('click', paint.updateCount); // paint.updateCount函數(shù)的this指向變成了該DOM對(duì)象 // 事件處理函數(shù)綁定的正確方法: document.querySelector('button') .addEventListener('click', paint.updateCount.bind(paint)); // paint.updateCount函數(shù)的this指向變成了paint
2.3 時(shí)間間隔函數(shù)
var notify = { text: "Hello World!", beforeRender: function() { alert(this.text); }, render: function() { // 錯(cuò)誤方法: setTimeout(this.beforeRender, 0); // undefined // 正確方法: setTimeout(this.beforeRender.bind(this), 0); // "Hello World!" } }; notify.render();
2.4 借用Array的原生方法
var a = {}; Array.prototype.push.bind(a, "hello", "world")(); console.log(a); // "hello", "world"
三. bind()方法的瀏覽器兼容性
四. bind()的兼容性寫(xiě)法
if (!Function.prototype.bind) { Function.prototype.bind = function() { var self = this, // 保存原函數(shù) context = [].shift.call(arguments), // 需要綁定的this上下文 args = [].slice.call(arguments); // 剩余的參數(shù)轉(zhuǎn)成數(shù)組 return function() { // 返回一個(gè)新函數(shù) // 執(zhí)行新函數(shù)時(shí),將傳入的上下文context作為新函數(shù)的this // 并且組合兩次分別傳入的參數(shù),作為新函數(shù)的參數(shù) return self.apply(context, [].concat.call(args, [].slice.call(arguments))); } }; }
五. bind與 call/apply方法的區(qū)別
共同點(diǎn):
都可以改變函數(shù)執(zhí)行的上下文環(huán)境;
不同點(diǎn):
bind: 不立即執(zhí)行函數(shù),一般用在異步調(diào)用和事件; call/apply: 立即執(zhí)行函數(shù)。
總結(jié)
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者使用Javascript能有一定的幫助,如果有疑問(wèn)大家可以留言交流。
- javascript使用eval或者new Function進(jìn)行語(yǔ)法檢查
- eval(function(p,a,c,k,e,d)系列解密javascript程序
- js eval函數(shù)使用,js對(duì)象和字符串互轉(zhuǎn)實(shí)例
- js中的eval()函數(shù)把含有轉(zhuǎn)義字符的字符串轉(zhuǎn)換成Object對(duì)象的方法
- AngularJs $parse、$eval和$observe、$watch詳解
- 關(guān)于動(dòng)態(tài)執(zhí)行代碼(js的Eval)實(shí)例詳解
- JS使用eval()動(dòng)態(tài)創(chuàng)建變量的方法
- javascript中JSON.parse()與eval()解析json的區(qū)別
- 深入淺析JSON.parse()、JSON.stringify()和eval()的作用詳解
- JS中Eval解析JSON字符串的一個(gè)小問(wèn)題
- 詳解Vue.js搭建路由報(bào)錯(cuò) router.map is not a function
- 淺談js中function的參數(shù)默認(rèn)值
- 淺析JS中對(duì)函數(shù)function的理解(基礎(chǔ)篇)
- JS中注入eval, Function等系統(tǒng)函數(shù)截獲動(dòng)態(tài)代碼
相關(guān)文章
javascript小數(shù)四舍五入多種方法實(shí)現(xiàn)
javascript小數(shù)四舍五入在工作中經(jīng)常會(huì)使用到,今天本文整理了一些常用的小竅門(mén),需要了解的朋友可以參考下2012-12-12JavaScript實(shí)現(xiàn)表單元素的操作
這篇文章介紹了JavaScript操作表單元素的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05JavaScript中的parse()方法使用簡(jiǎn)介
這篇文章主要介紹了JavaScript中的parse()方法使用簡(jiǎn)介,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06詳解JavaScript中g(shù)etFullYear()方法的使用
這篇文章主要介紹了詳解JavaScript中g(shù)etFullYear()方法的使用,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06JavaScript中Cookies的相關(guān)使用教程
這篇文章主要介紹了JavaScript中Cookies的相關(guān)使用教程,包括Cookies的存儲(chǔ)和刪除等操作方法,需要的朋友可以參考下2015-06-06