摘要:創(chuàng)建全局對象構(gòu)造函數(shù)一個變量一個對象容器嵌套對象命名約定通常以全部大寫的方式來命名這個全局對象。在命名模式中,有一個全局對象,在沙箱模式中,有一個全局構(gòu)造函數(shù),我們這里命名為。
在javascript中,我們知道可以使用對象字面量或者構(gòu)造函數(shù)創(chuàng)建對象,但是如何優(yōu)雅地創(chuàng)建一個對象你卻不一定了解。
前人在踩過無數(shù)坑又填過無數(shù)坑之后,給我們總結(jié)了不同場景下的幾種對象創(chuàng)建模式:
命名空間模
模塊模式
沙箱模式
鏈模式
命名模式有這樣一種場景,假如你正在寫一個插件,這個插件內(nèi)部會用到很多的全局變量,這時候你要怎么保證你的變量不會與其他插件的變量產(chǎn)生命名沖突呢?我們知道,在javascript中并沒有內(nèi)置命名空間,后面的變量會覆蓋掉前面的變量,你要如何避免這種問題的發(fā)生?
可能你已經(jīng)想到,只要足夠獨特的命名就可以了吧,比如lynneShowVar,這樣確實是可以的,但是如果變量很多,難道要為每個都起一個很獨特的命名?是不是很累?而且維護也是很麻煩的。
命名模式提出,為應(yīng)用程序創(chuàng)建一個全局對象,比如MYAPP,然后將所有的變量和函數(shù)掛到這個全局對象(MYAPP)的屬性上。
//創(chuàng)建全局對象 var MYAPP = {}; //構(gòu)造函數(shù) MYAPP.parent = function () {}; MYAPP.child = function () {}; //一個變量 MYAPP.some_var = 1; //一個對象容器 MYAPP.modules = {} //嵌套對象 MYAPP.modules.module1 = {}; MYAPP.modules.module2 = {};
命名約定:通常以全部大寫的方式來命名這個全局對象。
優(yōu)點:
避免代碼中的命名沖突
避免代碼與第三方的命名沖突
缺點
需要輸入更多字符
任何部分的代碼都可以修改全局實例
嵌套的額數(shù)字意味著更長的屬性查詢解析。
那么,有什么辦法可以避免這些缺陷么?聲明代碼依賴關(guān)系應(yīng)該是一個不錯的主意了。
聲明依賴關(guān)系
var myFunction = function () { //依賴 var event = MYAPP.util.event, dom = MYAPP.util.dom; //... }
優(yōu)點:
可讀性強
解析局部變量的速度總是比解析全局變量的速度快
減小代碼量
通用命名空間
隨著程序的復(fù)雜度的增加,如何保證全局對象上新添屬性不會覆蓋原有的屬性呢。這就需要每次在添加新屬性之前先檢查它是否已經(jīng)存在了。
var MYAPP = MYAPP || {}; MYAPP.name = function (ns_string) { var parts = ns_string.split("."), parent = MYAPP, i; //剝離最前面的冗余全局變量 if (parts[0] === "MYAPP") { parts = parts.slice(1); } for(i = 0; i < parts.length; i++) { //如果不存在就創(chuàng)建一個屬性 if (typeof parent[parts[i]] === "undefined") { parent[parts[i]] = {}; } parent = parent[parts[i]]; } return parent; }
命名模式雖然好用,但還是有個問題,那就是任何部分的代碼都可以修改全局實例,以及里面的屬性,怎么避免?我們知道es5并沒有類的概念,如果要實現(xiàn)私有成員,可以使用閉包來 模擬這種特性。
模塊模式其實模塊模式是多種模式的組合
命名空間
即時函數(shù)
私有和特權(quán)函數(shù)
聲明依賴
MYAPP.ntilities.array = (function () { //依賴 var uobj = MYAPP.ntilities.object, ulang = MYAPP.ntilities.lang; //私有屬性 var array_string = "[object array]", ops = Object.prototype.toString; //私有方法 //... //其它 //共有API return { inArray: function (needle, haystack) { ... }, isArray: function (str) { ... } //更多... } })()
將全局變量導(dǎo)入到模塊中
可以將參數(shù)傳遞到包裝了模塊的即時函數(shù)中,有助于加速即時函數(shù)中全局符號的解析。
MYAPP.ntilities.array = (function (app, global) { }(MYAPP, this);沙箱模式
假設(shè)需要在同一個頁面運行同一個庫的兩個版本,很遺憾,前面兩種創(chuàng)建模式都是不支持的。這時候就需要模塊化。
在命名模式中,有一個全局對象 ,在沙箱模式中,有一個全局構(gòu)造函數(shù),我們這里命名為Sandbox()。這個構(gòu)造函數(shù)可以接收一個或多個參數(shù),這些參數(shù)指定對象實例需要的模塊名,以及一個回調(diào)函數(shù)。如:
//模塊名可以使用數(shù)組的形式傳參 Sandbox(["ajax", "dom"], function () { //這里是回調(diào)函數(shù) }); //模塊名也可以使用單個參數(shù)的形式傳參,參數(shù)之間使用,號隔開 Sandbox("ajax", "dom", function () { //這里是回調(diào)函數(shù) }); //不指定模塊名稱或指定"*",表示需要依賴所有模塊 Sandbox(function () { //這里是回調(diào)函數(shù) }); Sandbox("*", function () { //這里是回調(diào)函數(shù) });
在實現(xiàn)實際的構(gòu)造函數(shù)之前,先為Sandbox添加一個名為modules的靜態(tài)屬性,這需要理解的是Sandbox同時也是一個對象。
Sandbox.modules = {}
把需要的模塊添加到Sandbox.modules對象中。假設(shè)我們一共需要dom、ajax、event模塊
Sandbox.modules.dom = function(box) { box.getElement = function () {}; }; Sandbox.modules.ajax = function(box) { box.getResponse = function () {}; }; Sandbox.modules.event = function(box) { box.attachEvent = function () {}; };
接下來實現(xiàn)構(gòu)造函數(shù)
function Sandbox = function () { //將參數(shù)轉(zhuǎn)換成一個數(shù)組 var args = Array.prototype.slice.call(arguments), //最后一個參數(shù)是回調(diào)函數(shù) callback = args.pop(), //args[0]如果是String類型,說明模塊作為多帶帶參數(shù)傳遞,否則模塊作為數(shù)組形式傳遞 modules = (args[0] && typeof args[0] === "String") ? args : arg[0], i; //確保該函數(shù)作為構(gòu)造函數(shù)調(diào)用 if(!(this instanceof Sandbox)) { return new Sandbox (modules, callback); } //需要向this添加的屬性,也可能沒有,這里看實際項目需求 this.a = 1; this.b = 2; //現(xiàn)在向該核心"this"對象添加模塊 //不指定模塊名稱或指定"*",都表示制定所有模塊 if (!modules || modules === "*") { modules = []; for (i in Sandbox.modules) { modules.push[i]; } } //初始化所需的模塊 for(i = 0; i < modules.lenght; i++) { Sandbox.modules[modules[i]](this) } //依賴模塊已全部初始化,可以執(zhí)行回調(diào)函數(shù) callback(); } //獲取你還需要添加一些原型屬性,看需求 Sanndbox.prototype = { name: "MY Application", version: "1.0", getName: function () { return this.name; } };
優(yōu)點
實現(xiàn)模塊化,解決 同一個頁面不能 使用同一個庫的不同版本的問題
優(yōu)化了以點分割的名字的解析時間,如:MYAPP.untilities.array
鏈?zhǔn)侥J?/b>鏈?zhǔn)侥J娇梢允鼓軌蛞粋€接一個地調(diào)用對象的方法,而無需將前一個操作返回的值付給變量,且無需分割成多行。如:
myobj.method1("hello").method2().method3("str");
這個很好理解,我們直接來看一看代碼
var obj = { al: 1, add: function (v) { this.val += v; return this; }, set: function (v) { this.val = v; return this; }, shout: function (v) { console.log(this.val); } }; //鏈方法調(diào)用 obj.add(1).set(2).shout();
可以看到,obj的每個方法都返回this對象,這就是實現(xiàn)鏈?zhǔn)降脑怼?/p>
優(yōu)點
節(jié)省輸入的字符
有助于分割函數(shù),提高代碼的維護性
缺點
難以調(diào)試,一旦出現(xiàn)問題,難以定位到具體步驟
每種設(shè)計模式都各有優(yōu)缺點,具體使用哪種模式還得看項目需求,大家一起學(xué)習(xí)吧。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85191.html
摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對象經(jīng)歷了以下四個過程創(chuàng)建一個新對象構(gòu)造函數(shù)的作用域交給新對象。 ??在創(chuàng)建對象的時候,使用對象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個對象是最簡單最方便的方式。但是凡是處于初級階段的事物都會不可避免的存在一個問題,沒有普適性,意思就是說我要為世界上(程序中)的所有使用到的對象都使用一遍 var xxx = {} ,...
摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對象經(jīng)歷了以下四個過程創(chuàng)建一個新對象構(gòu)造函數(shù)的作用域交給新對象。 ??在創(chuàng)建對象的時候,使用對象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個對象是最簡單最方便的方式。但是凡是處于初級階段的事物都會不可避免的存在一個問題,沒有普適性,意思就是說我要為世界上(程序中)的所有使用到的對象都使用一遍 var xxx = {} ,...
摘要:停更許久,近期計劃更新設(shè)計模式系列。單例模式是創(chuàng)建型設(shè)計模式的一種。雖然它不是正規(guī)的單例模式,但不可否認(rèn)確實具備類單例模式的特點。適用場景單例模式的特點,意圖解決維護一個全局實例對象。 停更許久,近期計劃更新:設(shè)計模式系列。 showImg(https://segmentfault.com/img/bVbt7uw?w=800&h=600); 單例模式:限制類實例化次數(shù)只能一次,一個類只...
摘要:但是,這并不是采用單例的唯一原因。使用命名空間單例模式也被稱為模塊設(shè)計模式。函數(shù)內(nèi)部聲明了一些局部函數(shù)和或變量。緊隨函數(shù)聲明放置即可立即執(zhí)行外部函數(shù),并將所得的對象文字費賠給變量。 JavaScript設(shè)計模式-第一部分:單例模式、組合模式和外觀模式 設(shè)計模式是一些可靠的編程方式,有助于保證代碼更加易于維護、擴展及分離,所有設(shè)計模式在創(chuàng)建大型JavaScript應(yīng)用程序時均不可或缺 單...
摘要:此時我們創(chuàng)建的對象內(nèi)保存靜態(tài)變量通過取值器訪問,最后將這個對象作為一個單例放在全局空間里面作為靜態(tài)變量單例對象供他人使用。 單例模式 又被稱為單體模式,是只允許實例化一次的對象類。有時我們也用一個對象來規(guī)劃一個命名空間,井井有條的管理對象上面的屬性和方法。 傳統(tǒng)的面向?qū)ο笳Z言中單例模式的實現(xiàn),均是單例對象從類中創(chuàng)建而來,在以類為中心的語言中,這是很常見的做法。如果需要某個對象,就必須先...
摘要:三種使用構(gòu)造函數(shù)創(chuàng)建對象的方法和的作用都是在某個特殊對象的作用域中調(diào)用函數(shù)。這種方式還支持向構(gòu)造函數(shù)傳遞參數(shù)。叫法上把函數(shù)叫做構(gòu)造函數(shù),其他無區(qū)別適用情境可以在特殊的情況下用來為對象創(chuàng)建構(gòu)造函數(shù)。 一、工廠模式 工廠模式:使用字面量和object構(gòu)造函數(shù)會有很多重復(fù)代碼,在此基礎(chǔ)上改進showImg(https://segmentfault.com/img/bVbmKxb?w=456&...
閱讀 2919·2021-10-19 10:09
閱讀 3140·2021-10-09 09:41
閱讀 3391·2021-09-26 09:47
閱讀 2702·2019-08-30 15:56
閱讀 604·2019-08-29 17:04
閱讀 993·2019-08-26 11:58
閱讀 2515·2019-08-26 11:51
閱讀 3369·2019-08-26 11:29