亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

javascript中的Function.prototye.bind

2019-11-20 12:08:59
字體:
來源:轉載
供稿:網友

函數綁定(Function binding)很有可能是你在開始使用JavaScript時最少關注的一點,但是當你意識到你需要一個解決方案來解決如何在另一個函數中保持this上下文的時候,你真正需要的其實就是 Function.prototype.bind(),只是你有可能仍然沒有意識到這點。

第一次遇到這個問題的時候,你可能傾向于將this設置到一個變量上,這樣你可以在改變了上下文之后繼續引用到它。很多人選擇使用 self, _this 或者 context 作為變量名稱(也有人使用 that)。這些方式都是有用的,當然也沒有什么問題。但是其實有更好、更專用的方式。

我們真正需要解決的問題是什么?
在下面的例子代碼中,我們可以名正言順地將上下文緩存到一個變量中:

var myObj = {   specialFunction: function () {   },   anotherSpecialFunction: function () {   },   getAsyncData: function (cb) {    cb();  },   render: function () {    var that = this;    this.getAsyncData(function () {      that.specialFunction();      that.anotherSpecialFunction();    });  }}; myObj.render();

如果我們簡單地使用 this.specialFunction() 來調用方法的話,會收到下面的錯誤:

Uncaught TypeError: Object [object global] has no method 'specialFunction'
我們需要為回調函數的執行保持對 myObj 對象上下文的引用。 調用 that.specialFunction()讓我們能夠維持作用域上下文并且正確執行我們的函數。 然而使用 Function.prototype.bind() 可以有更加簡潔干凈的方式:

render: function () {   this.getAsyncData(function () {     this.specialFunction();     this.anotherSpecialFunction();   }.bind(this)); }

我們剛才做了什么?
.bind()創建了一個函數,當這個函數在被調用的時候,它的 this 關鍵詞會被設置成被傳入的值(這里指調用bind()時傳入的參數)。因此,我們傳入想要的上下文,this(其實就是 myObj),到.bind()函數中。然后,當回調函數被執行的時候, this 便指向 myObj 對象。

如果有興趣想知道 Function.prototype.bind() 內部長什么樣以及是如何工作的,這里有個非常簡單的例子:

Function.prototype.bind = function (scope) {  var fn = this;  return function () {    return fn.apply(scope);  };}

還有一個非常簡單的用例:

var foo = {  x: 3} var bar = function(){  console.log(this.x);} bar(); // undefined var boundFunc = bar.bind(foo); boundFunc(); // 3

我們創建了一個新的函數,當它被執行的時候,它的 this 會被設置成 foo ―― 而不是像我們調用 bar() 時的全局作用域。

瀏覽器支持
Browser Version support
Chrome 7
Firefox (Gecko) 4.0 (2)
Internet Explorer 9
Opera 11.60
Safari 5.1.4
正如你看到的,很不幸,Function.prototype.bind 在IE8及以下的版本中不被支持,所以如果你沒有一個備用方案的話,可能在運行時會出現問題。

幸運的是,Mozilla Developer Network(很棒的資源庫),為沒有自身實現 .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,                aArgs.concat(Array.prototype.slice.call(arguments)));    };   fNOP.prototype = this.prototype;  fBound.prototype = new fNOP();   return fBound; };}

適用的模式

在學習技術點的時候,我發現有用的不僅僅在于徹底學習和理解概念,更在于看看在手頭的工作中有沒有適用它的地方,或者比較接近它的的東西。我希望,下面的某些例子能夠適用于你的代碼或者解決你正在面對的問題。

CLICK HANDLERS(點擊處理函數)
一個用途是記錄點擊事件(或者在點擊之后執行一個操作),這可能需要我們在一個對象中存入一些信息,比如:

var logger = {  x: 0,      updateCount: function(){    this.x++;    console.log(this.x);  }}

我們可能會以下面的方式來指定點擊處理函數,隨后調用 logger 對象中的 updateCount() 方法。

document.querySelector('button').addEventListener('click', function(){  logger.updateCount();});

但是我們必須要創建一個多余的匿名函數,來確保 updateCount()函數中的 this 關鍵字有正確的值。

我們可以使用如下更干凈的方式:

document.querySelector('button').addEventListener('click', logger.updateCount.bind(logger));
我們巧妙地使用了方便的 .bind() 函數來創建一個新的函數,而將它的作用域綁定為 logger 對象。

SETTIMEOUT
如果你使用過模板引擎(比如Handlebars)或者尤其使用過某些MV*框架(從我的經驗我只能談論Backbone.js),那么你也許知道下面討論的關于在渲染模板之后立即訪問新的DOM節點時會遇到的問題。

假設我們想要實例化一個jQuery插件:

var myView = {   template: '/* 一個包含 <select /> 的模板字符串*/',   $el: $('#content'),   afterRender: function () {    this.$el.find('select').myPlugin();  },   render: function () {    this.$el.html(this.template());    this.afterRender();  }} myView.render();

你或許發現它能正常工作――但并不是每次都行,因為里面存在著問題。這是一個競爭的問題:只有先到達的才能獲勝。有時候是渲染先到,而有時候是插件的實例化先到。【譯者注:如果渲染過程還沒有完成(DOM Node還沒有被添加到DOM樹上),那么find(‘select')將無法找到相應的節點來執行實例化?!?/p>

現在,或許并不被很多人知曉,我們可以使用基于 setTimeout() 的 slight hack來解決問題。

我們稍微改寫一下我們的代碼,就在DOM節點加載后再安全的實例化我們的jQuery插件:

afterRender: function () {    this.$el.find('select').myPlugin();  },   render: function () {    this.$el.html(this.template());    setTimeout(this.afterRender, 0);      }

然而,我們獲得的是 函數 .afterRender() 不能找到 的錯誤信息。

我們接下來要做的,就是將.bind()使用到我們的代碼中:

//   afterRender: function () {    this.$el.find('select').myPlugin();  },   render: function () {    this.$el.html(this.template());    setTimeout(this.afterRender.bind(this), 0);      } //

以上所述就是本文的全部內容了,希望大家能夠喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品久久久久久下一站| 国产美女精品视频免费观看| 亚洲第一偷拍网| 激情亚洲一区二区三区四区| 午夜免费久久久久| 日韩电影网在线| 国产精品91在线| 精品久久久久久久久国产字幕| 欧美寡妇偷汉性猛交| 亚洲三级 欧美三级| 91久久精品国产91性色| 日韩中文字幕视频在线| 日本久久久久久久久久久| 久久久久久成人精品| 中文字幕在线看视频国产欧美在线看完整| 久久中文精品视频| 最近2019中文免费高清视频观看www99| 精品日韩视频在线观看| 欧美性猛交xxxx乱大交蜜桃| 日本成人黄色片| 久久成人这里只有精品| 欧美电影院免费观看| 欧洲s码亚洲m码精品一区| 亚洲天堂影视av| 26uuu另类亚洲欧美日本一| 中文字幕日韩综合av| 欧美激情免费在线| 性欧美长视频免费观看不卡| 狠狠做深爱婷婷久久综合一区| 日韩精品丝袜在线| 国产日韩欧美在线看| 成人网址在线观看| 在线播放亚洲激情| 国产精品极品在线| 国产精品日韩欧美综合| 成人欧美一区二区三区在线| 日韩精品福利网站| 日韩电影第一页| 亚洲一区二区久久久久久| 亚洲男女自偷自拍图片另类| 亚洲精品国产综合久久| 久热99视频在线观看| 日韩av一卡二卡| 另类图片亚洲另类| 国产成人亚洲综合| 中文欧美在线视频| 色久欧美在线视频观看| 精品伊人久久97| 亚洲国产成人精品久久| 中文字幕亚洲综合| 亚洲国模精品私拍| 欧美激情视频给我| 91在线观看免费| 欧美精品第一页在线播放| 亚洲欧美中文日韩v在线观看| 久久人人爽人人爽人人片av高请| 欧美性资源免费| 中文字幕少妇一区二区三区| 日韩欧美精品在线观看| 亚洲成人久久电影| 久久夜色精品国产| 久久影院资源网| 精品视频在线播放免| 国产精品入口免费视| 欧美激情在线有限公司| 亚洲男人的天堂网站| 国产精品福利在线观看网址| 欧美激情喷水视频| 97精品视频在线观看| 91在线观看免费观看| xvideos成人免费中文版| 永久555www成人免费| 色综久久综合桃花网| 午夜欧美不卡精品aaaaa| 精品亚洲一区二区三区在线观看| 欧美一区二区三区免费观看| 色噜噜狠狠色综合网图区| 国产精品爱久久久久久久| 国产精品jizz在线观看麻豆| 国产精品自产拍高潮在线观看| 日本欧美一级片| 亚洲精品国精品久久99热一| 国产一区二区日韩精品欧美精品| 亚州成人av在线| 国产精品丝袜视频| 自拍视频国产精品| 久久91亚洲精品中文字幕| 欧美另类老女人| 日韩中文字幕在线| 久久天天躁狠狠躁夜夜躁2014| 国产精品高清在线观看| 91亚洲精品一区| 日韩av在线免费观看一区| 久久中文字幕一区| 性色av一区二区三区| 国产精品视频一| 成人伊人精品色xxxx视频| 8x海外华人永久免费日韩内陆视频| 国产日韩av在线| 国内精品久久久久久| 欧美性猛交视频| 欧美精品久久久久| 日韩av不卡电影| 亚洲性视频网址| 国产欧美精品在线| 欧美小视频在线观看| 欧美小视频在线| 中文字幕一精品亚洲无线一区| 国产精品视频一区国模私拍| 久久亚洲电影天堂| 欧美精品精品精品精品免费| 日本老师69xxx| 在线观看中文字幕亚洲| 国内外成人免费激情在线视频网站| 国产成人自拍视频在线观看| 欧美电影在线观看完整版| 色婷婷**av毛片一区| 久久久国产在线视频| 538国产精品一区二区免费视频| 久久精品99无色码中文字幕| 欧美天堂在线观看| 亚洲性猛交xxxxwww| 欧美激情一二三| 国产91色在线|| 亚洲国产成人在线视频| 欧美视频一二三| 日日骚久久av| 人妖精品videosex性欧美| 亚洲欧美在线x视频| 久久久精品2019中文字幕神马| 欧美一区亚洲一区| 日韩中文在线不卡| 在线视频中文亚洲| 大伊人狠狠躁夜夜躁av一区| 欧洲成人在线视频| 97成人精品视频在线观看| 中文字幕亚洲无线码a| 欧美日韩国产成人| 欧美劲爆第一页| 欧美xxxx18国产| 亚洲区一区二区| 粉嫩老牛aⅴ一区二区三区| 中文字幕亚洲一区| 国产精品久久久久久久9999| www.久久撸.com| 亚洲电影av在线| 久久在线免费视频| 精品国产乱码久久久久酒店| 亚洲视频日韩精品| 日本高清视频一区| 精品视频在线播放| 日本一区二区在线播放| 在线日韩av观看| 日韩av一区二区在线| 日韩中文视频免费在线观看| 亚洲另类激情图| 久久精品99国产精品酒店日本| 国产精品一区av| 国产精品69精品一区二区三区| 欧美在线视频一二三| 色偷偷噜噜噜亚洲男人的天堂| 日韩电影中文字幕在线| 亚洲精美色品网站| 日韩av成人在线|