Javascript模块模式编程的深入分析

基本知识

首先,我们需要知道模块的模式(2007 ericmiraglia YUI的博客)。如果您熟悉模块模式,可以跳过此部分并直接读取高级模式。

匿名函数闭包

匿名函数闭包是Javascript的最佳特性,它并不是所有的功能都能实现。现在我们创建一个匿名函数并立即执行它。函数中的所有代码都在闭包中执行,闭包决定了整个执行过程中代码的私有和状态。

复制代码代码如下所示:
(函数(){())
所有的变量和函数 / /…仅在此范围内
保持访问所有的全局变量 / /
}();


注意匿名函数之外的括号,这是因为在Javascript中以函数开始的语句通常被认为是一个函数声明。

全球进口

Javascript有一个功能叫做隐藏全局变量。当一个变量名时,编译器将使用var来声明变量的语句上。这个变量是全局如果没找到。如果你用这个当你指定一个值,你创造了一个全球范围,这意味着它是建立在一个匿名闭包的一个全局变量很容易。不幸的是,这将导致代码管理困难,因为对于程序员来说,如果全局变量不在一个文件中声明,它将非常清楚。幸运的是,匿名函数给了我另一个选择。我们可以导入到我们的代码通过全局变量匿名函数的参数,这是更快速和整洁。

复制代码代码如下所示:
($,函数,雅虎){
访问全局变量jQuery /现在(美元),这个代码雅虎
}(jQuery,雅虎);


模块的出口

有时您不希望使用全局变量,但希望声明它们,我们可以通过匿名函数的返回值轻松地导出它们。

复制代码代码如下所示:
var模块=(函数(){())
var,
privatevariable = 1;

功能privatemethod(){

}

my.moduleproperty = 1;
my.modulemethod =函数(){

};

我回;
}();


在这里我们声明一个全局模块调用的模块,它有两个公共属性:一种称为module.modulemethod和变量称为module.moduleproperty.in之外,他保持内部状态通过匿名函数的闭包。当然,我们也可以使用上面提到的模式轻松导入所需的全局变量。

高级模式

前面提到的内容已经满足了很多需求,但是我们可以更深入地研究这个模式来创建一些强大的、可伸缩的结构。

扩大

目前,一个模块的模式的局限性是整个模块必须写在一个文件中。每个人谁开发了一个大的代码代码知道分离成多个文件一个文件的重要性。幸运的是,我们必须扩展模块的一个好方法。首先,我们导入一个模块,然后添加属性,然后出口。这里的例子是用上述方法扩展模块。

复制代码代码如下所示:
var模块=(函数(我){)
my.anothermethod =函数(){
添加的方法…
};

我回;
}(模块);


这是没有必要的,但为保持一致,我们使用var关键字了。然后执行代码,和模块增加了一个公共的方法称为module.anothermethod.the扩展文件还保持其内部状态和进口。

Sunto的展览

我们上面的例子需要我们创建模块,然后扩展模块,这是没有必要的。异步加载脚本是一种提高Javascript应用程序性能的最佳途径。通过放松,我们创建了一个灵活的模块可以装在任何顺序分为多个文件,每个文件的结构如下

复制代码代码如下所示:
var模块=(函数(我){)
添加 / /能力…

我回;
(模块)| | } { });


在这种模式中,var声明是必须的。如果进口模块不存在,它将被创建。这意味着你可以和LABjs一样的工具并行加载这些模块文件。

收紧

虽然它很棒,但它也给您的模块增加了一些限制,最重要的一点是您不能安全地重写模块的属性。初始化时不能使用其他文件的模块属性,但可以在初始化后运行它。紧凑扩展包含一定的加载顺序,但它支持重写,这里是一个示例(扩展我们的原始模块)。

复制代码代码如下所示:
var模块=(函数(我){)
无功old_modulemethod = my.modulemethod;

my.modulemethod =函数(){
/ /访问方法重写,老通过old_modulemethod…
};

我回;
}(模块);


在这里,我们重写了module.modulemethod,我们保留了原有方法的参考要求。

复制与传承

复制代码代码如下所示:
无功module_two =(功能(旧){
var,
关键;

对于(键在旧){
如果(old.hasownproperty(关键)){
我的{旧};
}
}

无功super_modulemethod = old.modulemethod;
my.modulemethod =函数(){
在 / /重写clone方法,通过super_modulemethod获得超
};

我回;
}(模块);


这种模式可能是最灵活的选择。虽然它支持一些优雅的并购成本在灵巧的费用。我们写的代码,这些类型的对象或函数将不会被复制,只有在一个对象的两个引用的形式。一换,另一个为对象{ G5 },我们可以通过一个递归克隆操作解决它,但是没有办法的功能,除了提高。然而,我仍然包含了完整的缘故。

交叉文件私有状态

将一个模块划分为多个文件是一个很大的限制,也就是说,每个文件都保持其私有状态,并且无法获得其他文件的私有状态。

复制代码代码如下所示:
var模块=(函数(我){)
无功_private =我。_private =我。_private { } | |,
_seal =我。_seal =我。_seal(功能){ | |
我_private删除;
我_seal删除;
我_unseal删除;
},
_unseal =我。_unseal =我。_unseal(功能){ | |
我_private = _private;
我_seal = _seal;
我_unseal = _unseal;
};

访问 / /永久_private,_seal,_unseal

我回;
(模块)| | } { });


每个文件可以设置为私有变量,_private性质,和其他文件可以直接调用。模块加载时,程序调用模块。_seal(),是没有出路的内部_。private.if模块再次扩大后,其中一个属性将被改变。之前新的文件被加载,每个文件可以叫_。unsea(),然后_。密封后执行代码称为。

这个模型在我今天的工作中被考虑过,我还没有在其他地方看到它,但是我认为它是一个非常有用的模型,值得一个人去写。

子模块

最后的高层次的模式其实是最简单的,还有创建子模块的例子很多,就像创建一个通用模块。

复制代码代码如下所示:
module.sub =(功能){
var;


我回;
}();


尽管它很简单,但我还是认为它值得一写,子模块具有通用模块的所有质量特性,包括扩展和私有状态。

总结

最先进的模式可以进行组合,创造出更多的有用的新模式。如果我要提出一个设计复杂的应用程序的方法,我将结合松散膨胀,私有状态,和子模块。

我不提性能相关的事情,但我可以说,模块模型的性能改进的好,它可以减少代码量,使代码加载速度更快。松拓展使得并行加载的可能,这也增加了加载速度。初始化的时间可能比其他方法长,但值得花更多的时间。只要全局变量被正确导入并运行,不会有问题的。在子模块中,由于变量的引用链被缩短,它也将加速。

最后,这是子模块动态加载的一个例子(如果它不存在)。介绍,我不考虑内部的状态,但即使考虑到它是非常简单的。这种模式允许复杂的,多级编码并行加载,包括子模块和其他所有的事情。

复制代码代码如下所示:
VaR工具=(功能(父母,$){
我parent.ajax = parent.ajax var = {} | |;

my.get =功能(URL参数,回调){
所以我在欺骗某人
返回。getJSON(URL参数,回调);
};

等…

回报父母;
(利用| | { } },jQuery));


我希望这些内容有用。请在下面留言分享你的想法,男孩和女孩,试着写一个更好,更模块化的Javascript。

文本链接:本樱桃翻译:王晓