摘要:從很早的版本就開始,是支持循環依賴的。比如下面的代碼會被編譯成要支持循環依賴其實有個要求,就是。不是的循環依賴是無解的循環依賴。所以在初始化階段,這樣的循環依賴是被允許的,因為都是。
循環依賴
循環依賴是非常必要的,有的程序寫著寫著就循環依賴了,可以提取出一個對象來共同依賴解決循環依賴,但是有時會破壞程序的邏輯自封閉和高內聚。所以沒解決好循環依賴的模塊化庫、框架、編譯器都不是一個好庫、框架、編譯器。
kmdjs的本質就是{},從{}擴展出的tree。從很早的版本就開始,是支持循環依賴的。比如下面的代碼:
define("namespace1.A",["namespace2"], { ctor: function () { this.b = new B(); } }) define("namespace2.B",["namespace1"] , { ctor: function () { }, xx: function () { var a = new A(); } })
會被kmdjs編譯成:
var namespace1 = {}; var namespace2 = {}; namespace1.A = Class.extend({ ctor: function () { this.b = new namespace2.B(); } }) namespace2.B = Class.extend({ ctor: function () { }, xx: function () { var a = new namespace1.A(); } })
要支持循環依賴其實有個要求,就是lazy using。不是lazy using的循環依賴是無解的循環依賴。
怎么理解上面這句話呢?看上面的代碼,Class.extend執行完之后,各自依賴的東西是不會被調用的。
A代碼里的new namespace2.B()要在new namespace1.A的時候才會被調用。
B代碼里的new namespace1.A()要var a = new namespace1.A;a.xx()之后被調用后才會被執行。
所以在初始化階段,這樣的循環依賴是被允許的,因為都是lazy using。只要滿足lazy using,執行順序就不重要了,如果不是lazy using(如靜態屬性方法的設置),執行順序就必須把依賴的項先執行。
如上面所說,不是所有的循環依賴都能夠解決的,比如看C#里面的無解的循環依賴的例子:
namespace Project1 { public class A { public static B b = new B(); } } namespace Project1 { public class B { public static A a = new A(); } }
上面的代碼編譯時候就會報錯。怎么改成有解,那么就要lazy using:
namespace Project1 { public class A { public static B b = new B(); } } namespace Project1 { public class B { public int testMethod() { A a = new A(); return 1; } } }
這樣的依賴編譯器是可以解決的。
kmdjs 0.1.4kmd的意思是 kernel module definition。該版本和以前的主要變化如下:
kmdjs文件大小從以前的一萬多行代碼變成了一百多行代碼
從以前的namespace+class組織項目變成namespace+module組織項目
kmdjs APIkmdjs.config
用于配置 namespace + module和文件路徑的mapping
kmdjs.config({ "util.bom":"js/util/bom.js", "app.Ball":"js/ball.js", "util.dom":"js/util/dom.js", "util.dom.test":"js/util/test.js", "main": "js/main.js" });
kmdjs.main
程序的入口代碼。
kmdjs.define
定義模塊
kmdjs.define("main",["util.bom","app.Ball","util.dom.test"], function(bom,Ball,test) { var ball = new Ball(0, 0, 28, 1, -2, "kmdjs"); alert(test.m(3, 3)); var vp = bom.getViewport(); setInterval(function () { ball.tick(); (ball.x + ball.r * 2 > vp[2] || ball.x < 0) && (ball.vx *= -1); (ball.y + ball.r * 2 > vp[3] || ball.y < 0) && (ball.vy *= -1); }, 15); });
如果只傳兩個參數,代表不依賴任何模塊。這里和AMD一樣,在factory的回調里把依賴注入到里面。
但是也直接在代碼里把namespace寫進去訪問,如下所示:
kmdjs.define("main",["util.bom","app.Ball"], function() { var ball = new app.Ball(0, 0, 28, 1, -2, "kmdjs"); var vp = util.bom.getViewport(); setInterval(function () { ball.tick(); (ball.x + ball.r * 2 > vp[2] || ball.x < 0) && (ball.vx *= -1); (ball.y + ball.r * 2 > vp[3] || ball.y < 0) && (ball.vy *= -1); }, 15); });
而有的時候必須使用上面這種方式用來解決循環依賴導致執行順序問題帶來的注入undefined:如:
kmdjs.define("util.dom",["util.bom"] ,function(bom){ var Dom={}; Dom.add = function(a,b){ //循環依賴導致的bom undefined,所以這里寫上namespace return util.bom.sub(a,b); } return Dom; });
和
kmdjs.define("util.bom",["util.dom"], function(dom){ var Bom={}; Bom.getViewport=function() { alert(dom.add(1,4)); }; Bom.sub = function(a,b){ return a-b; }; return Bom; });bundler
可以通過main傳入回調函數,在回調函數中拿到編輯打包好的字符串。
kmdjs.main(function(bundler){ alert(bundler) });
如上面的例子打包出來的代碼:
var util={}; var app={}; util.dom={}; var main={}; util.dom = (function (bom){ var Dom={}; Dom.add = function(a,b){ return util.bom.sub(a,b); } return Dom; })(util.bom); app.Ball = (function (){ var Ball = function (x, y, r, vx, vy, text) { this.x = x; this.y = y; this.r = r; this.d = 2 * r; this.vx = vx; this.vy = vy; this.element = document.createElement("div"); this.element.innerHTML = text; this.element.style.cssText = "text-align:center;position:absolute; -moz-border-radius:" + this.d + "px; border-radius: " + this.d + "px; width: " + this.d + "px; height: " + this.d + "px;background-color:green;line-height:" + this.d + "px;color:white;"; document.body.appendChild(this.element); }; Ball.prototype.tick= function () { this.x += this.vx; this.y += this.vy; this.element.style.left = this.x + "px"; this.element.style.top = this.y + "px"; }; return Ball; })(); util.dom.test = (function (){ var Element={}; Element.m = function(a,b){ return a*b; } return Element; })(); util.bom = (function (dom){ var Bom={}; Bom.getViewport=function() { alert(dom.add(1,4)); var d = document.documentElement, b = document.body, w = window, div = document.createElement("div"); div.innerHTML = " "; var lt = !(div.firstChild.nodeType === 3) ? { left: b.scrollLeft || d.scrollLeft, top: b.scrollTop || d.scrollTop } : { left: w.pageXOffset, top: w.pageYOffset }; var wh = w.innerWidth ? { width: w.innerWidth, height: w.innerHeight } : (d && d.clientWidth && d.clientWidth != 0 ? { width: d.clientWidth, height: d.clientHeight } : { width: b.clientWidth, height: b.clientHeight }); return [lt.left, lt.top, wh.width, wh.height] }; Bom.sub = function(a,b){ return a-b; }; return Bom; })(util.dom); main = (function (bom,Ball,test) { var ball = new Ball(0, 0, 28, 1, -2, "kmdjs"); alert(test.m(3, 3)); var vp = bom.getViewport(); setInterval(function () { ball.tick(); (ball.x + ball.r * 2 > vp[2] || ball.x < 0) && (ball.vx *= -1); (ball.y + ball.r * 2 > vp[3] || ball.y < 0) && (ball.vy *= -1); }, 15); })(util.bom,app.Ball,util.dom.test);Github
https://github.com/kmdjs/kmdjs
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/79656.html
摘要:怎樣才算更好不用依賴注入不用寫,自動匹配依賴如下所示這就要借助能力,把的字符串替換成帶有就可以實現上面的效果。再也不用區分循環依賴和非循環依賴了上面的所有代碼可以上找到 回顧 上篇文章大概展示了kmdjs0.1.x時期的編程范式:如下面所示,可以直接依賴注入到function里, kmdjs.define(main,[util.bom,app.Ball,util.dom.test], ...
摘要:創建實例時,將遍歷的屬性,通過的將它們轉為,在其內部可以追蹤依賴通知變化。在內部,同是響應的觀察屬性變化的實例提供了方法,用于觀察屬性變化。 響應系統是 Vue 一個顯著功能,修改屬性,可以更新視圖,這讓狀態管理變得非常簡單且直觀。創建 Vue 實例時,Vue 將遍歷 data 的屬性,通過 ES5 的 Object.defineProperty 將它們轉為 getter/setter...
摘要:下一代查詢語言,使支持緣由最近剛好修改了騰訊文檔表格公式的一些,主要是修改公式的。總的來說,因為騰訊文檔公式相關工作早年的開發和開發,所以有了。讓前端工程師通過字符串的形式實現了的調用下面統一叫做,即組成的。多數據源多數據源會產生笛卡兒積。 Qone 下一代 Web 查詢語言,使 javascript 支持 LINQ Github: https://github.com/dntzha...
摘要:我們知道為我們完全實例化好一個一定會經過一下三步實例化,其實也就是調用對象的構造方法實例化對象。循環依賴的產生定會發生在步驟和中,因為是利用構造方法,是利用屬性賦值。 引言 基于Spring5+ 什么是循環依賴? 循環依賴有幾種? Spring可以解決哪幾種,為什么不能解決這幾種? Spring是如何判斷存在循環依賴的? 什么是循環依賴? 什么是循環依賴?我們都知道Spring最大...
閱讀 2095·2021-11-24 10:34
閱讀 3074·2021-11-22 11:58
閱讀 3729·2021-09-28 09:35
閱讀 1741·2019-08-30 15:53
閱讀 2792·2019-08-30 14:11
閱讀 1567·2019-08-29 17:31
閱讀 559·2019-08-26 13:53
閱讀 2155·2019-08-26 13:45