亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript Module Pattern: In-Depth

2019-11-10 21:08:22
字體:
來源:轉載
供稿:網友

NOTE:  This referenced article is obviously a bit old it is though a great one, which will lead you to wide areas in implementing module-based JS PRogramming. So, if you are interested in modular means with JS programming, please go on reading...

The module pattern is a common javaScript coding pattern. It’s generally well understood, but there are a number of advanced uses that have not gotten a lot of attention. In this article, I’ll review the basics and cover some truly remarkable advanced topics, including one which I think is original.

The Basics

We’ll start out with a simple overview of the module pattern, which has been well-known since Eric Miraglia (of YUI) first blogged about it three years ago. If you’re already familiar with the module pattern, feel free to skip ahead to “Advanced Patterns”.

Anonymous Closures

This is the fundamental construct that makes it all possible, and really is the single best feature of Javascript. We’ll simply create an anonymous function, and execute it immediately. All of the code that runs inside the function lives in a closure, which provides privacy and state throughout the lifetime of our application.

(function () {	// ... all vars and functions are in this scope only	// still maintains access to all globals}());

Notice the () around the anonymous function. This is required by the language, since statements that begin with the tokenfunction are always considered to be function declarations. Including () creates a function expression instead.

Global Import

JavaScript has a feature known as implied globals. Whenever a name is used, the interpreter walks the scope chain backwards looking for a var statement for that name. If none is found, that variable is assumed to be global. If it’s used in an assignment, the global is created if it doesn’t already exist. This means that using or creating global variables in an anonymous closure is easy. Unfortunately, this leads to hard-to-manage code, as it’s not obvious (to humans) which variables are global in a given file.

Luckily, our anonymous function provides an easy alternative. By passing globals as parameters to our anonymous function, weimport them into our code, which is both clearer and faster than implied globals. Here’s an example:

(function ($, YAHOO) {	// now have access to globals jQuery (as $) and YAHOO in this code}(jQuery, YAHOO));

Module Export

Sometimes you don’t just want to use globals, but you want to declare them. We can easily do this by exporting them, using the anonymous function’s return value. Doing so will complete the basic module pattern, so here’s a complete example:

var MODULE = (function () {	var my = {},		privateVariable = 1;	function privateMethod() {		// ...	}	my.moduleProperty = 1;	my.moduleMethod = function () {		// ...	};	return my;}());

Notice that we’ve declared a global module named MODULE, with two public properties: a method namedMODULE.moduleMethod and a variable named MODULE.moduleProperty. In addition, it maintains private internal stateusing the closure of the anonymous function. Also, we can easily import needed globals, using the pattern we learned above.

Advanced Patterns

While the above is enough for many uses, we can take this pattern farther and create some very powerful, extensible constructs. Lets work through them one-by-one, continuing with our module named MODULE.

Augmentation

One limitation of the module pattern so far is that the entire module must be in one file. Anyone who has worked in a large code-base understands the value of splitting among multiple files. Luckily, we have a nice solution to augment modules. First, we import the module, then we add properties, then we export it. Here’s an example, augmenting our MODULE from above:

var MODULE = (function (my) {	my.anotherMethod = function () {		// added method...	};	return my;}(MODULE));

We use the var keyWord again for consistency, even though it’s not necessary. After this code has run, our module will have gained a new public method named MODULE.anotherMethod. This augmentation file will also maintain its own private internal state and imports.

Loose Augmentation

While our example above requires our initial module creation to be first, and the augmentation to happen second, that isn’t always necessary. One of the best things a JavaScript application can do for performance is to load scripts asynchronously. We can create flexible multi-part modules that can load themselves in any order with loose augmentation. Each file should have the following structure:

var MODULE = (function (my) {	// add capabilities...	return my;}(MODULE || {}));

In this pattern, the var statement is always necessary. Note that the import will create the module if it does not already exist. This means you can use a tool like LABjs and load all of your module files in parallel, without needing to block.

Tight Augmentation

While loose augmentation is great, it does place some limitations on your module. Most importantly, you cannot override module properties safely. You also cannot use module properties from other files during initialization (but you can at run-time after intialization). Tight augmentation implies a set loading order, but allows overrides. Here is a simple example (augmenting our original MODULE):

var MODULE = (function (my) {	var old_moduleMethod = my.moduleMethod;	my.moduleMethod = function () {		// method override, has access to old through old_moduleMethod...	};	return my;}(MODULE));

Here we’ve overridden MODULE.moduleMethod, but maintain a reference to the original method, if needed.

Cloning and Inheritance

var MODULE_TWO = (function (old) {	var my = {},		key;	for (key in old) {		if (old.hasOwnProperty(key)) {			my[key] = old[key];		}	}	var super_moduleMethod = old.moduleMethod;	my.moduleMethod = function () {		// override method on the clone, access to super through super_moduleMethod	};	return my;}(MODULE));

This pattern is perhaps the least flexible option. It does allow some neat compositions, but that comes at the expense of flexibility. As I’ve written it, properties which are objects or functions will not be duplicated, they will exist as one object with two references. Changing one will change the other. This could be fixed for objects with a recursive cloning process, but probably cannot be fixed for functions, except perhaps with eval. Nevertheless, I’ve included it for completeness.

Cross-File Private State

One severe limitation of splitting a module across multiple files is that each file maintains its own private state, and does not get access to the private state of the other files. This can be fixed. Here is an example of a loosely augmented module that willmaintain private state across all augmentations:

var MODULE = (function (my) {	var _private = my._private = my._private || {},		_seal = my._seal = my._seal || function () {			delete my._private;			delete my._seal;			delete my._unseal;		},		_unseal = my._unseal = my._unseal || function () {			my._private = _private;			my._seal = _seal;			my._unseal = _unseal;		};	// permanent access to _private, _seal, and _unseal	return my;}(MODULE || {}));

Any file can set properties on their local variable _private, and it will be immediately available to the others. Once this module has loaded completely, the application should call MODULE._seal(), which will prevent external access to the internal_private. If this module were to be augmented again, further in the application’s lifetime, one of the internal methods, in any file, can call _unseal() before loading the new file, and call _seal() again after it has been executed. This pattern occurred to me today while I was at work, I have not seen this elsewhere. I think this is a very useful pattern, and would have been worth writing about all on its own.

Sub-modules

Our final advanced pattern is actually the simplest. There are many good cases for creating sub-modules. It is just like creating regular modules:

MODULE.sub = (function () {	var my = {};	// ...	return my;}());

While this may have been obvious, I thought it worth including. Sub-modules have all the advanced capabilities of normal modules, including augmentation and private state.

Conclusions

Most of the advanced patterns can be combined with each other to create more useful patterns. If I had to advocate a route to take in designing a complex application, I’d combine loose augmentation, private state, and sub-modules.

I haven’t touched on performance here at all, but I’d like to put in one quick note: The module pattern is good for performance. It minifies really well, which makes downloading the code faster. Using loose augmentation allows easy non-blocking parallel downloads, which also speeds up download speeds. Initialization time is probably a bit slower than other methods, but worth the trade-off. Run-time performance should suffer no penalties so long as globals are imported correctly, and will probably gain speed in sub-modules by shortening the reference chain with local variables.

To close, here’s an example of a sub-module that loads itself dynamically to its parent (creating it if it does not exist). I’ve left out private state for brevity, but including it would be simple. This code pattern allows an entire complex heirarchical code-base to be loaded completely in parallel with itself, sub-modules and all.

var UTIL = (function (parent, $) {	var my = parent.Ajax = parent.ajax || {};	my.get = function (url, params, callback) {		// ok, so I'm cheating a bit :)		return $.getJSON(url, params, callback);	};	// etc...	return parent;}(UTIL || {}, jQuery));

I hope this has been useful, and please leave a comment to share your thoughts. Now, go forth and write better, more modular JavaScript!

登錄樂搏學院官網http://www.learnbo.com/

或關注我們的官方微博微信,還有更多驚喜哦~


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩av电影院| 亚洲第一免费播放区| 久久久噜久噜久久综合| 国产亚洲精品久久久久久牛牛| 欧洲成人在线视频| 成人有码视频在线播放| 久久福利视频网| 国产精品自产拍高潮在线观看| 日韩在线视频导航| 欧美日韩国产精品一区| 久久精品电影网| www.久久久久久.com| 一级做a爰片久久毛片美女图片| 91精品在线影院| 中文在线资源观看视频网站免费不卡| 亚洲欧美国产精品| 亚州成人av在线| 久久久久久伊人| 91天堂在线视频| 久久影视电视剧免费网站| 欧美日韩精品中文字幕| 91精品国产综合久久香蕉| www.xxxx精品| 色综合91久久精品中文字幕| 国产一级揄自揄精品视频| 精品久久久999| 亚洲香蕉在线观看| 欧美日韩xxx| 久久精品久久久久| 久久综合色影院| 亚洲最大的网站| 91国内在线视频| 欧美午夜片欧美片在线观看| 精品国产一区二区三区久久久| 欧美中文字幕在线观看| 亚洲福利视频专区| 日韩av中文字幕在线免费观看| 精品国产欧美成人夜夜嗨| 日本高清不卡在线| 亚洲自拍在线观看| 国产精品福利在线观看网址| 日本一区二区不卡| 久久国产精彩视频| 欧美另类第一页| 亚洲色图色老头| 精品国产91久久久久久老师| 日韩在线激情视频| 欧美日韩在线观看视频| 欧美日韩成人在线视频| 97精品国产97久久久久久| 26uuu另类亚洲欧美日本一| 亚洲网站在线看| 国产精品久久久久久久久粉嫩av| 亚洲一区美女视频在线观看免费| 久久久亚洲国产| 欧美激情在线观看视频| 国产午夜精品麻豆| 国产精品1234| 精品在线小视频| 日韩免费观看视频| 欧美刺激性大交免费视频| 日韩在线小视频| 亚洲深夜福利在线| 黑人极品videos精品欧美裸| 亚洲美女福利视频网站| 国内精品视频久久| 北条麻妃在线一区二区| 久久韩剧网电视剧| 久久久久久久国产精品| 国产不卡一区二区在线播放| 中文字幕欧美精品在线| 国产91久久婷婷一区二区| 综合久久五月天| 热99精品只有里视频精品| 97精品免费视频| 欧美国产精品人人做人人爱| 久久久视频免费观看| 亚洲成人精品视频在线观看| 久久久久久久久爱| 亚洲在线观看视频网站| 成人在线国产精品| 日本中文字幕久久看| 日韩欧美精品免费在线| 中文字幕日韩欧美在线| 久久国产精品免费视频| 亚洲欧洲在线看| 综合网日日天干夜夜久久| 国产日韩精品视频| 亚洲男人av电影| 亚洲视频免费一区| 亚洲人成电影网| 欧美日韩午夜视频在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 成人免费视频xnxx.com| 日韩亚洲精品电影| 中文字幕视频一区二区在线有码| 国产精品入口日韩视频大尺度| 国产精品久久在线观看| 亚洲老司机av| 91成人精品网站| 午夜精品一区二区三区在线| 欧美另类在线播放| 中文字幕亚洲综合久久筱田步美| 亚洲精品久久久久中文字幕二区| 精品国产视频在线| 欧美综合在线第二页| 91理论片午午论夜理片久久| 亚洲精品一区二区网址| 欧美激情视频在线| 国产精品综合网站| 国产视频久久久久久久| 亚洲在线免费观看| 精品国偷自产在线| 国产精品精品一区二区三区午夜版| 日韩免费在线观看视频| 性欧美在线看片a免费观看| 欧美激情精品久久久久久黑人| 久久久成人的性感天堂| 欧美乱妇高清无乱码| 欧美天天综合色影久久精品| 欧美在线中文字幕| 91chinesevideo永久地址| 亚洲美女精品成人在线视频| 亚洲一区二区三区视频| 国产午夜精品一区二区三区| 日本久久亚洲电影| 91精品国产91久久久久久久久| 国产裸体写真av一区二区| 久久99热这里只有精品国产| 欧美成人精品在线播放| 亚洲欧美综合另类中字| 91精品综合久久久久久五月天| 精品国产乱码久久久久酒店| 国产精品∨欧美精品v日韩精品| 日韩在线中文视频| 久久91精品国产91久久跳| 亚洲人成电影在线| 久久亚洲国产成人| 揄拍成人国产精品视频| 国模精品视频一区二区| 亚洲女人被黑人巨大进入al| 欧美精品久久久久| 国产精品美女www爽爽爽视频| 日韩av在线一区| 色噜噜国产精品视频一区二区| 久久色免费在线视频| 亚洲精品日韩激情在线电影| 亚洲国产精品久久精品怡红院| 欧美在线影院在线视频| 国产成人jvid在线播放| 97久久精品人搡人人玩| 黑人巨大精品欧美一区免费视频| 欧美激情视频免费观看| 欧美一级淫片aaaaaaa视频| 亚洲91精品在线观看| 国产精品爽爽爽| 操日韩av在线电影| 久久精品91久久香蕉加勒比| 亚洲人成在线播放| 视频在线观看99| 欧美日韩国产丝袜美女| 在线视频精品一| 国产日本欧美一区二区三区在线| 久久久久久com|