最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

javascript中的Function.prototye.bind

 更新時間:2015年06月25日 11:26:55   投稿:hebedich  
這篇文章主要介紹了javascript中的Function.prototye.bind的相關(guān)資料,需要的朋友可以參考下

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

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

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

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() 來調(diào)用方法的話,會收到下面的錯誤:

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

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

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

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

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

我們創(chuàng)建了一個新的函數(shù),當(dāng)它被執(zhí)行的時候,它的 this 會被設(shè)置成 foo —— 而不是像我們調(diào)用 bar() 時的全局作用域。

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

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

適用的模式

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

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

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

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

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

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

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

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

SETTIMEOUT
如果你使用過模板引擎(比如Handlebars)或者尤其使用過某些MV*框架(從我的經(jīng)驗(yàn)我只能談?wù)揃ackbone.js),那么你也許知道下面討論的關(guān)于在渲染模板之后立即訪問新的DOM節(jié)點(diǎn)時會遇到的問題。

假設(shè)我們想要實(shí)例化一個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();

你或許發(fā)現(xiàn)它能正常工作——但并不是每次都行,因?yàn)槔锩娲嬖谥鴨栴}。這是一個競爭的問題:只有先到達(dá)的才能獲勝。有時候是渲染先到,而有時候是插件的實(shí)例化先到?!咀g者注:如果渲染過程還沒有完成(DOM Node還沒有被添加到DOM樹上),那么find(‘select')將無法找到相應(yīng)的節(jié)點(diǎn)來執(zhí)行實(shí)例化。】

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

我們稍微改寫一下我們的代碼,就在DOM節(jié)點(diǎn)加載后再安全的實(shí)例化我們的jQuery插件:

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

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

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

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

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

相關(guān)文章

  • 深入理解JavaScript中async/await的錯誤處理方式

    深入理解JavaScript中async/await的錯誤處理方式

    在現(xiàn)代JavaScript開發(fā)中,異步編程是不可或缺的一部分,async和await是一種強(qiáng)大的異步編程工具,它們使得編寫和維護(hù)異步代碼更加容易和清晰,然而,異步操作仍然可能會出現(xiàn)錯誤,本文將深入探討async和await的錯誤處理方式,提供詳細(xì)的代碼示例和解釋
    2023-09-09
  • Bootstrap中CSS的使用方法

    Bootstrap中CSS的使用方法

    這篇文章主要為大家詳細(xì)介紹了Bootstrap中CSS的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Bootstrap滾動監(jiān)聽組件scrollspy.js使用方法詳解

    Bootstrap滾動監(jiān)聽組件scrollspy.js使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Bootstrap滾動監(jiān)聽組件scrollspy.js的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Javascript BOM學(xué)習(xí)小結(jié)(六)

    Javascript BOM學(xué)習(xí)小結(jié)(六)

    BOM:BrowserObjectModel,瀏覽器對象模型,提供JS中對瀏覽器的各種操作的對象,是JS應(yīng)用中唯一沒有相關(guān)標(biāo)準(zhǔn)的部分,這事BOM經(jīng)常出現(xiàn)問題的所在,主要用于處理瀏覽器窗口與框架,瀏覽器特有的JS擴(kuò)展也被默認(rèn)為BOM的一部分,而各瀏覽器之間的公有對象就成了默認(rèn)的標(biāo)準(zhǔn)
    2015-11-11
  • js輸入框郵箱自動提示功能代碼實(shí)現(xiàn)

    js輸入框郵箱自動提示功能代碼實(shí)現(xiàn)

    一個輸入框當(dāng)我輸入任何字的時候自動下拉相應(yīng)的郵箱提示,在輸入框輸入11的時候下拉框有所有11的郵箱 輸入其他的時候 有其他文案對應(yīng)的郵箱,下面實(shí)現(xiàn)這個自動提示功能
    2013-12-12
  • 保姆級Decimal.js使用教程(解決js精度問題)

    保姆級Decimal.js使用教程(解決js精度問題)

    這篇文章主要給大家介紹了關(guān)于保姆級Decimal.js使用的相關(guān)資料,文中介紹的方法主要解決了js精度問題,decimal.js庫它是一個強(qiáng)大的JavaScript庫,用于解決浮點(diǎn)數(shù)計(jì)算精度不準(zhǔn)確的問題,需要的朋友可以參考下
    2024-05-05
  • JavaScript實(shí)現(xiàn)無限級遞歸樹的示例代碼

    JavaScript實(shí)現(xiàn)無限級遞歸樹的示例代碼

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)無限級遞歸樹的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 20分鐘打造屬于你的Bootstrap站點(diǎn)

    20分鐘打造屬于你的Bootstrap站點(diǎn)

    20分鐘打造屬于你的Bootstrap站點(diǎn),學(xué)會使用twitter bootstrap建立一個站點(diǎn),從而鞏固Bootstrap一系列基礎(chǔ)知識,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Bootstrap 按鈕樣式與使用代碼詳解

    Bootstrap 按鈕樣式與使用代碼詳解

    這篇文章主要介紹了Bootstrap -- 按鈕樣式與使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-12-12
  • JS正則中的RegExp對象對象

    JS正則中的RegExp對象對象

    JavaScript提供了一個RegExp對象來完成有關(guān)正則表達(dá)式的操作和功能,每一條正則表達(dá)式模式對應(yīng)一個RegExp實(shí)例
    2012-11-11

最新評論

东辽县| 海南省| 信丰县| 法库县| 雷波县| 宁明县| 榕江县| 丰都县| 金堂县| 苍南县| 辉南县| 碌曲县| 乡城县| 凤台县| 榆社县| 曲周县| 城口县| 淳安县| 昔阳县| 阿巴嘎旗| 绍兴县| 成安县| 象州县| 托克托县| 琼结县| 峨眉山市| 顺平县| 台前县| 绥中县| 西宁市| 绥化市| 梁河县| 苏尼特左旗| 郓城县| 潼南县| 鞍山市| 漳州市| 高阳县| 新蔡县| 兴安盟| 漳浦县|