最新消息:

模块化编程的步骤和方法(js的模块化编程有哪些方式)

媒体模版 admin 浏览 评论

模块化编程是为了更好的管理工程、方便以后移植代码、使主函数或主文件(即有main函数的那个文件)变得简单,因为我们读代码时一般都是从主函数开始读的。

那怎么进行模块化呢?

简单的就是一个功能包装成一个函数,要实现什么功能就调用哪个函数实现。

而复杂点的就是,一个功能模块统一放一个C文件中,这个模块相关的函数全部在这个C文件中实现,在主文件(即有main函数的C文件)想要使用这个模块的功能函数,只需要包含它的头文件就可以调用了。那头文件就只是放这个功能模块的函数声明。

这样子做,以后移植就方便多了。如果别的工程需要这个功能模块,只需复制一下它的C文件已经H文件到这个工程目录下,就能使用。

比如实现LCD描字、划线、画圆等等函数都放在一个叫做lcd.c的文件中,那就应该有一个叫做lcd.h的文件跟它对应,这个.h都是放这个.c文件对外函数的声明。主文件的开头出只需来一个#include"lcd.h"就可以调用这些画圆划线函数了。

基础

我们首先简单地概述一下,自从三年前Eric Miraglia(YUI的开发者)第一次发表博客描述模块化模式以来的一些模块化模式。如果你已经对于这些模块化模式非常熟悉了,大可以直接跳过本节,从“进阶模式”开始阅读。

匿名闭包

这是一种让一切变为可能的基本结构,同时它也是Javascript最棒的特性。我们将简单地创建一个匿名函数并立即执行它。所有的代码将跑在这个函数内,生存在一个提供私有化的闭包中,它足以使得这些闭包中的变量能够贯穿我们的应用的整个生命周期。

复制代码代码如下:

(function(){

//... all vars and functions are in this scope only

// still maintains access to all globals

}());

注意这对包裹匿名函数的最外层括号。因为Javascript的语言特性,这对括号是必须的。在js中由关键词function开头的语句总是会被认为是函数声明式。把这段代码包裹在括号中就可以让解释器知道这是个函数表达式。

全局变量导入

Javascript有一个特性叫做隐式全局变量。无论一个变量名在哪儿被用到了,解释器会根据作用域链来反向找到这个变量的var声明语句。如果没有找到var声明语句,那么这个变量就会被视为全局变量。如果这个变量用在一句赋值语句中,同时这个变量又不存在时,就会创建出一个全局变量。这意味着在匿名闭包中使用或创建全局变量是很容易的。不幸的是,这会导致写出的代码极难维护,因为对于人的直观感受来说,一眼根本分不清那些是全局的变量。

幸运的是,我们的匿名函数提供了简单的变通方法。只要将全局变量作为参数传递到我们的匿名函数中,就可以得到比隐式全局变量更清晰又快速的代码了。下面是示例:

复制代码代码如下:

(function($, YAHOO){

// now have access to globals jQuery(as$) and YAHOO in this code

}(jQuery, YAHOO));

模块导出

有时你不仅想要使用全局变量,你还想要声明它们,以供反复使用。我们可以很容易地通过导出它们来做到这一点——通过匿名函数的返回值。这样做将会完成一个基本的模块化模式雏形,接下来会是一个完整的例子:

复制代码代码如下:

var MODULE=(function(){

var my={},

privateVariable= 1;

function privateMethod(){

//...

}

my.moduleProperty= 1;

my.moduleMethod= function(){

//...

};

return my;

}());

注意我们已经声明了一个叫做MODULE的全局模块,它拥有2个公有的属性:一个叫做MODULE.moduleMethod的方法和一个叫做MODULE.moduleProperty的变量。另外,它还维护了一个利用匿名函数闭包的、私有的内置状态。同时,我们可以很容易地导入需要的全局变量,并像之前我们所学到的那样来使用这个模块化模式。

进阶模式

上面一节所描述的基础已经足以应对许多情况,现在我们可以将这个模块化模式进一步的发展,创建更多强大的、可扩展的结构。让我们从MODULE模块开始,一一介绍这些进阶模式。

放大模式

整个模块必须在一个文件中是模块化模式的一个限制。任何一个参与大型项目的人都会明白将js拆分多个文件的价值。幸运的是,我们拥有一个很棒的实现来放大模块。首先,我们导入一个模块,并为它添加属性,最后再导出它。下面是一个例子——从原本的MODULE中放大它:

复制代码代码如下:

var MODULE=(function(my){

my.anotherMethod= function(){

// added method...

};

return my;

}(MODULE));

我们用var关键词来保证一致性,虽然它在此处不是必须的。在这段代码执行完之后,我们的模块就已经拥有了一个新的、叫做MODULE.anotherMethod的公有方法。这个放大文件也会维护它自己的私有内置状态和导入的对象。

宽放大模式

我们的上面例子需要我们的初始化模块最先被执行,然后放大模块才能执行,当然有时这可能也不一定是必需的。Javascript应用可以做到的、用来提升性能的、最棒的事之一就是异步执行脚本。我们可以创建灵活的多部分模块并通过宽放大模式使它们可以以任意顺序加载。每一个文件都需要按下面的结构组织:

复制代码代码如下:

var MODULE=(function(my){

// add capabilities...

return my;

}(MODULE||{}));

在这个模式中,var表达式使必需的。注意如果MODULE还未初始化过,这句导入语句会创建MODULE。这意味着你可以用一个像LABjs的工具来并行加载你所有的模块文件,而不会被阻塞。

紧放大模式

宽放大模式非常不错,但它也会给你的模块带来一些限制。最重要的是,你不能安全地覆盖模块的属性。你也无法在初始化的时候,使用其他文件中的属性(但你可以在运行的时候用)。紧放大模式包含了一个加载的顺序序列,并且允许覆盖属性。这儿是一个简单的例子(放大我们的原始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));

我们在上面的例子中覆盖了MODULE.moduleMethod的实现,但在需要的时候,可以维护一个对原来方法的引用。

克隆与继承

复制代码代码如下:

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));

这个模式可能是最缺乏灵活性的一种选择了。它确实使得代码显得很整洁,但那是用灵活性的代价换来的。正如我上面写的这段代码,如果某个属性是对象或者函数,它将不会被复制,而是会成为这个对象或函数的第二个引用。修改了其中的某一个就会同时修改另一个(译者注:因为它们根本就是一个啊!)。这可以通过递归克隆过程来解决这个对象克隆问题,但函数克隆可能无法解决,也许用eval可以解决吧。因此,我在这篇文章中讲述这个方法仅仅是考虑到文章的完整性。

跨文件私有变量

把一个模块分到多个文件中有一个重大的限制:每一个文件都维护了各自的私有变量,并且无法访问到其他文件的私有变量。但这个问题是可以解决的。这里有一个维护跨文件私有变量的、宽放大模块的例子:

复制代码代码如下:

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||{}));

所有文件可以在它们各自的_private变量上设置属性,并且它理解可以被其他文件访问。一旦这个模块加载完成,应用程序可以调用MODULE._seal()来防止外部对内部_private的调用。如果这个模块需要被重新放大,在任何一个文件中的内部方法可以在加载新的文件前调用_unseal(),并在新文件执行好以后再次调用_seal()。我如今在工作中使用这种模式,而且我在其他地方还没有见过这种方法。我觉得这是一种非常有用的模式,很值得就这个模式本身写一篇文章。

子模块

我们的最后一种进阶模式是显而易见最简单的。创建子模块有许多优秀的实例。这就像是创建一般的模块一样:

复制代码代码如下:

MODULE.sub=(function(){

var my={};

//...

return my;

}());

虽然这看上去很简单,但我觉得还是值得在这里提一提。子模块拥有一切一般模块的进阶优势,包括了放大模式和私有化状态。

步骤1:

首先,选择一个少儿程序学习软件。

目前,国内外有很多少儿编程软件。我认为对外国的偏好在于外国的信息技术水平,尤其是美国、英国、以色列等发达国家,他们比我们先进。在发达国家,创新、创造和编程教育比我们早得多,也更完善。Scratch无疑是目前最受孩子们欢迎的程序之一。它是麻省理工学院为孩子们设计和开发的一个工具。即使没有英文和键盘操作,用户也可以直接使用中文进行图形化编程,使用鼠标将模块拖动到程序编辑栏中,实现相应的功能,轻松创建动画、游戏。因此,建议刚开始学习的孩子从零开始。

步骤2:

其次,我们应该制定一个详细的学习计划并付诸实施。

虽然大多数编程程序都有详细的学习指南,但对孩子来说,详细的学习计划是必不可少的。这项工作必须由家长来做,这就要求家长成为编程的第一个学习者,熟练掌握。例如以色列的儿童编程游戏CodeMonkey,就是一个从简单到深入一步的学习,需要孩子们学习和体验每一个层次,才能真正学到扎实的编程知识。

步骤3:

多参加STEM相关的实践活动。

STEM教育起源于美国。1986年,美国国家科学委员会首次提出STEM教育的概念,即科学、技术、工程和数学。旨在帮助儿童在科学、技术、工程和数学领域全面发展,提高他们的全球竞争力。到目前为止,STEM教育以学科整合和PBL(基于问题的学习)的形式得到了广泛的开展。儿童编程属于T和m的典型结合和重要实践。此外,还有大量的技术实践,如编程机器人和无人机。有条件的家长应带子女参加。让幼儿充分体验跨领域项目的沉浸式实践,提高创新能力和创造力。

步骤4:

如果家庭条件允许,可以申请培训。

网上有很多自学教程。但首先,这是对父母的一个很高的要求,父母自己一定要学会。即使父母从事的是与计算机相关的职业,有相关的基础、时间,是否能够转化为孩子的学习指导也需要很多的考虑。如果父母自己什么都不知道,学习就更困难了。儿童编程自然是针对儿童的,但也包含了整个编程知识体系,没有专门的指导,就不会容易。如果你想让你的孩子学习编程,就带他一起去学吧。

转载请注明:片头模版 » 模块化编程的步骤和方法(js的模块化编程有哪些方式)

发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)

网友最新评论 ()