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

首頁 > 編程 > JavaScript > 正文

JavaScript Module Pattern: In-Depth

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

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
欧洲成人在线视频| 国产成人在线精品| 亚洲黄在线观看| 亚洲成人性视频| 国产日韩欧美另类| 中文字幕在线看视频国产欧美在线看完整| 亚洲成人黄色网| 欧美激情精品久久久久久蜜臀| 国产精品白嫩初高中害羞小美女| 亚洲自拍偷拍色图| 国产精品久久久久国产a级| 日韩av网站电影| 成人观看高清在线观看免费| 久久久久国产一区二区三区| 日韩免费看的电影电视剧大全| 亚洲视频一区二区三区| 亚洲第五色综合网| 国产a级全部精品| 精品久久国产精品| 精品日韩美女的视频高清| 精品成人在线视频| 欧美尺度大的性做爰视频| 国产精品99久久久久久人| 成人激情视频在线观看| 欧美日韩国产精品一区二区不卡中文| 69久久夜色精品国产69乱青草| 欧美日韩国产麻豆| 国产成人一区二区三区小说| 欧美一级在线播放| 久久久久久这里只有精品| 欧美精品福利在线| 亚洲色图欧美制服丝袜另类第一页| 三级精品视频久久久久| 久久久久久亚洲精品| 久久精品国产一区| 欧洲午夜精品久久久| 亚洲自拍高清视频网站| 亚洲欧美一区二区精品久久久| 久久免费国产精品1| 国模叶桐国产精品一区| 久久精品99久久久香蕉| 91中文字幕一区| www.日本久久久久com.| 亚洲wwwav| 亚洲美女在线看| 日韩国产欧美精品一区二区三区| 国产精品免费观看在线| 精品国产欧美一区二区五十路| 57pao国产成人免费| 少妇高潮 亚洲精品| 成人日韩av在线| 国产欧美精品xxxx另类| 欧美裸体男粗大视频在线观看| 日韩久久午夜影院| 久久久亚洲精选| 国产欧美一区二区三区久久| 国产精品毛片a∨一区二区三区|国| yellow中文字幕久久| 国产精品成人v| 欧美日韩国产限制| 亚洲精品乱码久久久久久金桔影视| 日韩人在线观看| 美女999久久久精品视频| 国产成人a亚洲精品| 国产精品手机播放| 1769国产精品| 精品久久久久久久久久久久久| 久久人人爽人人爽人人片亚洲| 亚洲午夜未满十八勿入免费观看全集| 91po在线观看91精品国产性色| 亚洲夜晚福利在线观看| 欧美精品电影在线| 精品在线小视频| 亚洲第一视频在线观看| 国产成人拍精品视频午夜网站| 国产综合色香蕉精品| 国产98色在线| 欧美激情性做爰免费视频| 久久人人爽人人爽人人片av高清| 日韩色av导航| 91精品久久久久久| 在线播放国产一区二区三区| 久久久精品一区二区三区| 成人精品视频99在线观看免费| 欧美人成在线视频| 美女啪啪无遮挡免费久久网站| 精品国产精品自拍| 国产精品99久久久久久人| 在线播放国产一区中文字幕剧情欧美| 国产精品福利在线观看| 另类专区欧美制服同性| 啪一啪鲁一鲁2019在线视频| 国产一区二区色| 欧美高跟鞋交xxxxhd| 欧美中文在线观看| 日韩小视频在线| 亚洲精品福利在线| 国产精品h在线观看| 国产日韩欧美电影在线观看| 欧美一区二粉嫩精品国产一线天| 国产精品高清在线观看| 成人h视频在线| 一区二区三区视频免费| 久久久999国产精品| 777国产偷窥盗摄精品视频| 久久91亚洲精品中文字幕| 亚洲一区二区三区sesese| 亚洲人成网在线播放| 欧美性猛交xxxx免费看久久久| 欧美视频在线观看 亚洲欧| 国产91ⅴ在线精品免费观看| 欧美午夜激情视频| 精品成人在线视频| 欧美高清理论片| 国产精品久久久久久av下载红粉| 亚洲黄色有码视频| 亚洲电影免费观看高清完整版在线| 91欧美精品成人综合在线观看| 成人精品aaaa网站| 欧美午夜激情小视频| 国产91精品黑色丝袜高跟鞋| 韩国国内大量揄拍精品视频| 久久韩剧网电视剧| 精品国产老师黑色丝袜高跟鞋| 日韩专区中文字幕| 亚洲第一区中文字幕| 国产一区二区三区在线| 亚洲精品成人久久| 国产精品亚洲自拍| 国产91精品黑色丝袜高跟鞋| 欧美高清视频在线| 日本精品免费一区二区三区| 一区二区在线免费视频| 欧美日韩国产一区二区| 亚洲精品91美女久久久久久久| 亚洲欧洲黄色网| 国产精品久久久久久超碰| 欧美日韩中文字幕日韩欧美| 精品久久久久久中文字幕大豆网| 欧美日韩国产色视频| 中文日韩在线观看| 欧美日韩精品国产| 日韩欧美在线视频日韩欧美在线视频| 91精品国产综合久久香蕉的用户体验| 日韩中文在线不卡| 日韩精品小视频| 欧美肥老妇视频| 欧美激情精品久久久久久免费印度| 国产亚洲一区精品| 久久久中文字幕| 日韩av有码在线| 国产精品视频一区二区高潮| 国产黑人绿帽在线第一区| 国产精品久久久久久久久男| 亚洲系列中文字幕| 亚洲va久久久噜噜噜久久天堂| 日韩欧美精品免费在线| 亚洲精品日产aⅴ| 亚洲午夜av久久乱码| 91久久精品美女高潮| 亚洲男人天堂网站| 欧美中文字幕在线观看| 国产一区香蕉久久| 国语自产精品视频在免费|