摘要:用到了一個小技巧來防止誤傳入的覆蓋掉默認的值。的精粹都在這個函數(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._changing 和 this._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
摘要:整個的代碼非常簡潔,構(gòu)造邏輯也一目了然。生成唯一合并參數(shù)列表列表項目的初始化用戶定義的初始化事件處理可以看到,最重要的代碼,在于的初始化。這段代碼可以看出,如果實例化的時候有傳入一個節(jié)點,則綁定這個節(jié)點,否則生成一個這樣的節(jié)點。 整個View的代碼非常簡潔,View構(gòu)造邏輯也一目了然。 javascriptvar View = Backbone.View = function(opt...
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...
摘要:因為是一條數(shù)據(jù)記錄,也就是說,相當于是一個數(shù)據(jù)集。通常我們需要重載函數(shù),聲明,以及通過或為視圖指定根元素。通過綁定視圖的函數(shù)到模型的事件模型數(shù)據(jù)會即時的顯示在中。實例屬性參數(shù)以及類屬性參數(shù)會被直接注冊到集合的構(gòu)造函數(shù)。 對于初學backbone.js的同學可以先參考我這篇文章:Backbone.js學習筆記(一) Backbone源碼結(jié)構(gòu) showImg(https://segme...
摘要:以為例構(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)上隨隨便便就能找到一堆...
摘要:個人認為,讀懂老牌框架的源代碼比會用流行框架的要有用的多。另外,源代碼中所有的以開頭的方法,可以認為是私有方法,是沒有必要直接使用的,也不建議用戶覆蓋。 寫在前面 backbone是我兩年多前入門前端的時候接觸到的第一個框架,當初被backbone的強大功能所吸引(當然的確比裸寫js要好得多),雖然現(xiàn)在backbone并不算最主流的前端框架了,但是,它里面大量設(shè)計模式的靈活運用,以及令...
閱讀 1074·2021-11-12 10:34
閱讀 1001·2021-09-30 09:56
閱讀 676·2019-08-30 15:54
閱讀 2613·2019-08-30 11:14
閱讀 1476·2019-08-29 16:44
閱讀 3217·2019-08-29 16:35
閱讀 2501·2019-08-29 16:22
閱讀 2453·2019-08-29 15:39