国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Backbone源碼研究 - Backbone.Model

Steve_Wang_ / 2751人閱讀

摘要:用到了一個小技巧來防止誤傳入的覆蓋掉默認的值。的精粹都在這個函數(shù)里面。看到這,給各種打補丁就有了可行性,支持就用,不支持的則降級到走的這種方式。

前言

都因為 IE8 不支持 Object.defineProperty,但是業(yè)務(wù)還不能脫離 IE7 和 IE8,故研究下 Backbone.Model 的實現(xiàn)機制,找機會給主流的 MVVM 框架補丁

偽代碼

先來看看 Model 的構(gòu)造函數(shù)

var Model = Backbone.Model = function(attributes, options) {
    var attrs = attributes || {};
    options || (options = {});
    
    // 鉤子
    this.preinitialize.apply(this, arguments);
    
    // 每個實例分配一個唯一的 cid
    this.cid = _.uniqueId(this.cidPrefix);
    // 數(shù)據(jù)對象
    this.attributes = {};
    
    // 不重要的內(nèi)容
    if (options.collection) this.collection = options.collection;
    if (options.parse) attrs = this.parse(attrs, options) || {};
    
    // 獲取預(yù)設(shè)在 defaults 字段中的初始鍵值對或匿名函數(shù)
    // 這里使用 _.result() 來兼容函數(shù)和對象兩種類型
    var defaults = _.result(this, "defaults");
    
    // 避免 attrs 中的 undefined 值覆蓋掉 defaults 中的默認值
    attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
    
    // 初始化賦值
    this.set(attrs, options);
    this.changed = {};
    
    // 鉤子
    this.initialize.apply(this, arguments);
  };

很簡單的代碼,做了一些初始化賦值的事情。

用到了一個小技巧 attrs = _.defaults(_.extend({}, defaults, attrs), defaults); 來防止誤傳入的 undefined 覆蓋掉默認的 defaults 值。

Backbone 的精粹都在 set(){} 這個函數(shù)里面。

set: function(key, val, options) {
  if (key == null) return this;

  // 統(tǒng)一 "key", "val" 和 {key:val} 這兩種形式
  // attrs 最終為變動的對象
  var attrs;
  if (typeof key === "object") {
    attrs = key;
    options = val;
  } else {
    (attrs = {})[key] = val;
  }

  options || (options = {});

  // 規(guī)則驗證.
  if (!this._validate(attrs, options)) return false;

  var unset      = options.unset;
  var silent     = options.silent;
  var changes    = [];
  var changing   = this._changing;
  this._changing = true;

  // 預(yù)留上一次的值
  if (!changing) {
    this._previousAttributes = _.clone(this.attributes);
    this.changed = {};
  }

  // 備份一個當前的數(shù)據(jù)對象
  var current = this.attributes;
  var changed = this.changed;
  var prev    = this._previousAttributes;

  // 遍歷傳入的新數(shù)據(jù)對象
  for (var attr in attrs) {
    val = attrs[attr];
    
    // 如果新數(shù)據(jù)與當前不一致,則標記變動的鍵名
    if (!_.isEqual(current[attr], val)) changes.push(attr);
    
    // 如果新數(shù)據(jù)與舊數(shù)據(jù)不一致,則更新已變動的數(shù)據(jù)備份
    if (!_.isEqual(prev[attr], val)) {
      changed[attr] = val;
    } else {
      delete changed[attr];
    }
    
    // 真正干活的代碼,更新數(shù)據(jù)或者刪除數(shù)據(jù)
    unset ? delete current[attr] : current[attr] = val;
  }

  // 更新 id 字段
  if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);

  if (!silent) {
    if (changes.length) this._pending = options;
    
    // 遍歷變動清單,并且逐個觸發(fā) `change:` 事件
    for (var i = 0; i < changes.length; i++) {
      this.trigger("change:" + changes[i], this, current[changes[i]], options);
    }
  }

  if (changing) return this;
  if (!silent) {

    // 觸發(fā)一個總的 `change` 事件
    // 注釋說這里用 while 是確保嵌套場景也只觸發(fā)一個 `change` 事件
    while (this._pending) {
      options = this._pending;
      this._pending = false;
      this.trigger("change", this, options);
    }
  }
  this._pending = false;
  this._changing = false;
  return this;
},

整個 set 里面,實際干活的就是 unset ? delete current[attr] : current[attr] = val;

沒看明白 this._changingthis._pending 的使用場景,感覺是一個當多個 set 同時執(zhí)行時候的一個標記位,但是 JS 是單線程執(zhí)行,里面又都是 for 語句,按理說可以不用這兩個標記位。又或者是我的理解有誤。

more

看到這,給各種Observer打補丁就有了可行性,支持 Object.defineProperty 就用 Object.defineProperty,不支持的則降級到走 Backbone 的這種 for in 方式。

同步更新博客

https://www.mxgw.info/a/backb...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81330.html

相關(guān)文章

  • Backbone源碼研究 - Backbone.View

    摘要:整個的代碼非常簡潔,構(gòu)造邏輯也一目了然。生成唯一合并參數(shù)列表列表項目的初始化用戶定義的初始化事件處理可以看到,最重要的代碼,在于的初始化。這段代碼可以看出,如果實例化的時候有傳入一個節(jié)點,則綁定這個節(jié)點,否則生成一個這樣的節(jié)點。 整個View的代碼非常簡潔,View構(gòu)造邏輯也一目了然。 javascriptvar View = Backbone.View = function(opt...

    JellyBool 評論0 收藏0
  • Backbone 源碼解讀(一)

    1. 開場 1.1 MVC? MVC是一種GUI軟件的一種架構(gòu)模式。它的目的是將軟件的數(shù)據(jù)層(Model)和視圖(view)分開。Model連接數(shù)據(jù)庫,實現(xiàn)數(shù)據(jù)的交互。用戶不能直接和數(shù)據(jù)打交道,而是需要通過操作視圖,然后通過controller對事件作出響應(yīng),最后才得以改變數(shù)據(jù)。最后數(shù)據(jù)改變,通過觀察者模式更新view。(所以在這里需要用到設(shè)計模式中的觀察者模式) 1.2 Smalltalk-80...

    Kosmos 評論0 收藏0
  • Backbone.js學習筆記(二)細說MVC

    摘要:因為是一條數(shù)據(jù)記錄,也就是說,相當于是一個數(shù)據(jù)集。通常我們需要重載函數(shù),聲明,以及通過或為視圖指定根元素。通過綁定視圖的函數(shù)到模型的事件模型數(shù)據(jù)會即時的顯示在中。實例屬性參數(shù)以及類屬性參數(shù)會被直接注冊到集合的構(gòu)造函數(shù)。 對于初學backbone.js的同學可以先參考我這篇文章:Backbone.js學習筆記(一) Backbone源碼結(jié)構(gòu) showImg(https://segme...

    taoszu 評論0 收藏0
  • Backbone源碼解讀(二)

    摘要:以為例構(gòu)造函數(shù)的內(nèi)容構(gòu)造函數(shù)的內(nèi)部一般會做以下幾個操作各種給內(nèi)部對象設(shè)置屬性。為什么呢源碼做出了解釋。在里面會調(diào)用用戶傳入的回調(diào)函數(shù)并觸發(fā)事件表示已經(jīng)同步了。整個的源碼事實上就是這兩組東西。 1. 開場 強烈建議一邊看著源碼一邊讀本文章,本文不貼大段代碼。源碼地址。在寫backbone應(yīng)用的時候,說實話,大部分的時間都是在寫這三個模塊的內(nèi)容。關(guān)于這三個模塊的分析網(wǎng)上隨隨便便就能找到一堆...

    Sleepy 評論0 收藏0
  • backbone源碼解讀

    摘要:個人認為,讀懂老牌框架的源代碼比會用流行框架的要有用的多。另外,源代碼中所有的以開頭的方法,可以認為是私有方法,是沒有必要直接使用的,也不建議用戶覆蓋。 寫在前面 backbone是我兩年多前入門前端的時候接觸到的第一個框架,當初被backbone的強大功能所吸引(當然的確比裸寫js要好得多),雖然現(xiàn)在backbone并不算最主流的前端框架了,但是,它里面大量設(shè)計模式的靈活運用,以及令...

    Kross 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<