@@ -386,3 +386,83 @@ JavaScript不像Java或者其它语言,它没有专门的提供私有、保护
386
386
myarray.indexOf = null;
387
387
myarray.inArray(["a", "b", "z"], "z"); // 2
388
388
389
+ ## 模块模式
390
+
391
+ 模块模式使用得很广泛,因为它可以为代码提供特定的结构,帮助组织日益增长的代码。不像其它语言,JavaScript没有专门的“包”(package)的语法,但模块模式提供了用于创建独立解耦的代码片段的工具,这些代码可以被当成黑盒,当你正在写的软件需求发生变化时,这些代码可以被添加、替换、移除。
392
+
393
+ 模块模式是我们目前讨论过的好几种模式的组合,即:
394
+
395
+ - 命名空间模式
396
+ - 立即执行的函数模式
397
+ - 私有和特权成员模式
398
+ - 依赖声明模式
399
+
400
+ 第一步是初始化一个命名空间。我们使用本章前面部分的` namespace() ` 函数,创建一个提供数组相关方法的套件模块:
401
+
402
+ MYAPP.namespace('MYAPP.utilities.array');
403
+
404
+ 下一步是定义模块。使用一个立即执行的函数来提供私有作用域供私有成员使用。立即执行的函数返回一个对象,也就是带有公有接口的真正的模块,可以供其它代码使用:
405
+
406
+ MYAPP.utilities.array = (function () {
407
+ return {
408
+ // todo...
409
+ };
410
+ }());
411
+
412
+ 下一步,给公有接口添加一些方法:
413
+
414
+ MYAPP.utilities.array = (function () {
415
+ return {
416
+ inArray: function (needle, haystack) {
417
+ // ...
418
+ },
419
+ isArray: function (a) {
420
+ // ...
421
+ }
422
+ };
423
+ }());
424
+
425
+ 如果需要的话,你可以在立即执行的函数提供的闭包中声明私有属性和私有方法。函数顶部也是声明依赖的地方。在变量声明的下方,你可以选择性地放置辅助初始化模块的一次性代码。函数最终返回的是一个包含模块公共API的对象:
426
+
427
+ MYAPP.namespace('MYAPP.utilities.array');
428
+ MYAPP.utilities.array = (function () {
429
+
430
+ // dependencies
431
+ var uobj = MYAPP.utilities.object,
432
+ ulang = MYAPP.utilities.lang,
433
+
434
+ // private properties
435
+ array_string = "[object Array]",
436
+ ops = Object.prototype.toString;
437
+
438
+ // private methods
439
+ // ...
440
+ // end var
441
+
442
+ // optionally one-time init procedures
443
+ // ...
444
+
445
+ // public API
446
+ return {
447
+
448
+ inArray: function (needle, haystack) {
449
+ for (var i = 0, max = haystack.length; i < max; i += 1) {
450
+ if (haystack[i] === needle) {
451
+ return true;
452
+ }
453
+ }
454
+ },
455
+
456
+ isArray: function (a) {
457
+ return ops.call(a) === array_string;
458
+ }
459
+ // ... more methods and properties
460
+ };
461
+ }());
462
+
463
+ 模块模式被广泛使用,这是一种值得强烈推荐的模式,它可以帮助组织代码,尤其是代码量在不断增长的时候。
464
+
465
+
466
+
467
+
468
+
0 commit comments