前言

之前我做过一个web app(原来可以这么叫啦),在一个页面上有很多小窗口,每个小窗口都是独立的应用,比如:

① 我们一个小窗口数据来源是腾讯微博,需要形成腾讯微博app小窗口

② 我们一个小窗口数据来源新浪微博,需要形成新浪微博的小窗口

我们注意到以上2个的数据源与处理方式较一致,但是需要做处理,而且其鉴权也不尽相同,所以这个js代码有相同的,也有不相同的。

③ 我们的一个小窗口数据来源于百度RSS,需要形成点击标题展开的功能

④ 我们一个小窗口数据来源于XXX,其表现形式为选项卡......

⑤ 我们一个小窗口是flash,需要......

⑥ 我们一个小窗口是个综合应用,里面还会有定时器,自动的更新其数据

......

① 点击最大化图标会最大化窗口,里面的数据滚屏分页

② 拖动排序,点击选择图标分配(导航上有不同的类)

③ 新闻预览,类似于google效果

④ 延迟加载

......

各位,这些功能都在一个页面呢,我们的js该怎么组织了,我们的js要怎么写才能让后来的人读的清晰呢?

然后,响应式布局流行了,小叶你去搞下,实现响应式布局!

然后,瀑布流很火,小叶不然把瀑布流也加上

然后,纯屏设计出来了,小叶,将我们的程序设置一下吧,用户可以选择自己想要的。。。

......

我们知道一个网站干不了这么多事情,但是一个公司不是研发最大,不是产品最大,而是老板最大!

老板说需要,那就必须需要,你不行就闪开,有人行。

我们这里先不说风云变幻的需求,就说以上应用,面对不停增加的不停种类的小窗口,我们应当如何组织,并且控制我们的javascript代码呢???

javascript之路

javascript最初使用并没有那么复杂,基本就是一个页面一个js解决问题,但是现在情况变了,我们的js现在需要干的事情不比后端少了,而且还有越来越多的趋势!

在这个时候很多后端的东西便直接上来了:

① MVC

② MVVM

③ 模块化编程

④ 设计模式

以上的提出都是为了更好的帮助前端兄弟组织自己的代码,但是我们知道一个事实:

设计模式这个东西没有几年扎实的功底根本就达不到一个高度,比如本人,在刚毕业时候还在搞.net便看了几本设计模式的书籍,自以为有所得,现在想来,尼玛的神马都不记得了!!!

所以,一个事实,前端很多兄弟,并且是比较优秀的兄弟,对设计模式了解不够深入啦(我反正不深)。

从优秀到高手的蜕变中,我们会写大量js代码,我们会发现,尼玛这一坨代码和那一坨代码好像长得有点像,

尼玛这三块代码感觉就只有一点差距啦!于是小钗就干过这个事情:

看着js里面有几块相同的,然后将它和到一个函数中了,并在函数中做了一点点变化,实现功能了,小钗看到少了几十行代码,小钗感到很高兴。

于是慢慢小钗在编程过程中有意无意的发现每次都会有几个家伙会重复,所以有一天小钗终于决定将至封装一番,从那以后,小钗遇到这个问题变不会写多余的代码了。

其实,通过以上的做法,优秀的程序员慢慢有了模块化编程的思想,或者面向对象编程的思维,刚开始以实现了很多的插件沾沾自喜,到后面点,就会站在框架与js/css代码的组织的高度审视整个项目的实现了。

这个时候他便是高手啦,但是有一段很长的路要走。。。

模块化编程

javascript时不存在类这种说法的,所以模块(module)就是一个传说(ECMAScipt第六版表示会支持)。

但是我们伟大的前端技术人员模拟实现了类这个家伙,最后还实现了模块这个家伙。

最初的想法:模块就是实现特定功能的一组方法

 function m1() {}
function m2() {}

将上面两个函数加在一起,便可直接调用,但是我们知道这种做法会导致全局对象污染,所以我们换个做法:

 var person = {
name: '叶小钗',
getName: function () {},
setName: function () {}
};

这样做又会导致内部的局部变量会被外部篡改,这显然不够“oop”,我们知道javascript唯一可以产生局部作用域的方式便是函数,所以我们有了这种写法:

 var Person = (function () {

 var name='叶小钗';
var getName: function () {};
var setName: function () {}; return {get: getName, set: setName}; })();

如此一来,我们内部的的变量就老实了,这样看上去也比较面向对象啦。

以上就是我们模块化编程的基本做法,下面来一点点变化,因为我们的模块可能会很大的:

当模块很大时,便需要用到“放大模式”,这些高级概念我们后面点再去理解。

 var person = (function (mod) {

 mod.getAge = function () {};

 ......

 })(Person);

我们看到我们原来是没有age这个变量的,所以我们一个模块需要用到的变量最好能在上面定义。

异步问题

以上的方式其实比较乐观,但是我们很多时候其实并不能保证person已经被定义了,所以上面的用法可能是错误的,这在异步编程模型中会经常遇到,这个时候我们有了一个“宽放大模式”:

 var person = (function (mod) {

  mod.getAge = function () {};

  ......

  })(Person || {});

做了一点点的变化,但是整个程序的容错度上升了。

模块化的重要性

模块化后,我们可以方便的使用其他同事的代码,也不必担心命名污染的问题了,目前通行的javascript模块规范有两种:CommonJS与AMD。

node.js这一神器的产物的诞生(我后面点会针对此写一个系列的文章,在此叮嘱自己),标志着javascript模块化编程正式诞生,因为网页一般不会很复杂,服务器的话,没有模块便做死吧。。。。

node.js的模块系统是参照CommonJS规范实现的,在CommonJS中有一个全局性方法require(),用于加载模块。

若是有一数学模块math.js,便可以如此解决:

 var math = require('math');
math.add(1, 4);

若是要搞node.js的兄弟先从这个家伙开始吧。

客服端的疑惑

以上的代码,我们知道第一行其实是会加载一段math.js的函数的,意思是我们下面的math.add要等到文件加载结束才行啦。。。这就是同步加载与异步加载的痛苦。

我们知道好的网站是不能容忍“假死”的,但是我们并不能知道网速等因素,所以同步的话,浏览器必定会假死,异步加载模型再一次出现{asynchronous},传说中的AMD。

AMD:Asynchronous Module Definition

异步模块定义,他采用异步方式加载模块,模块加载不影响后面语句执行,其实我们对他的实现应该非常熟悉的,想想我们的ajax啦:

 require('math', function (math) {
math.add();
});

这个内部发生了什么大家应该一目了然,应该和$.getScript是一个原理的。于是我们来介绍一个实现了AMD的javascript库:require.js

PS:初步印象,这样虽然是按需加载的,但是以我们之前小窗口的需求来说,我们可能每一个小窗口会对应一个js文件,页面小窗口过多(延迟加载可以忽略),可能导致同时加载几个js会不会对性能有影响吗?这里我们先不关注他。

我们来看看我们的require.js,他的提出为了解决以下问题:

① 实现javascript异步加载,避免页面假死

② 管理模块之间的依赖性,便于代码编写与维护(这是重点啊)

要使用require.js需要下载最新的版本。这里比较重要,我们单独开一段吧

require.js

我们先去官网下载脚本:http://requirejs.org/docs/release/2.1.6/r.js

他这个最让人兴奋的就是,我们可以如此指定一个头main入口文件:

<script src="js/require.js" data-main="js/main"></script>

比如我现在会一次性加载几个js文件:

 require (['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
// some code here
});

以上是主模块依稀三个模块的写法,若是主模块依赖于jquery的话:

require(['jquery'], function ($) {

});

AMD模块写法

require.js加载采用AMD规范,假定有一个math.js文件,他定义了一个math模块,那么math需要这样写:

//math.js
define(function () {
var func = function () {};
return {func: func};
});
//加载方式
require(['math'], function (math) {
//...
})

算了,关于require.js这块东西,我等下做几个例子再跟进吧,现在都不熟悉,说这么多也没用。

结语

这块东西我们暂时说道这里,接下来我们来使用一番require.js,以及来说下MVC与MVVM是神马东西吧。

参考:

http://kb.cnblogs.com/page/161717/

【javascript激增的思考01】模块化编程的更多相关文章

  1. JavaScript学习笔记-面向对象的模块化编程

    面向对象的模块化编程 模块是一个独立的JS文件,模块文件可以包含一个类定义.一组相关的类.一个实用函数库.一些待执行的代码 模块化的目标:支持大规模的程序开发,处理分散源代码的组装,并能让代码正确执行 ...

  2. 【javascript激增的思考02】模块化与MVC

    前言 之前我们遇到了这么一个项目,也就是我们昨天提到的,有很多的小窗口的,昨天说的太抽象了,今天我们再来理一理什么是小窗口(后面点说下),当时由于js有一点复杂,我自己也装B跟风用了一下传说中MVC! ...

  3. 【javascript激增的思考04】MVC与Backbone.js(beta)

    前言 最近整理了很多前端面试题的东西,今天又去参加了一次面试,不知各位烦不烦,我反正有点累了,于是我们今天继续回到我们前段时间研究的问题,我们再来看看MVC吧. 什么是MVC 又回到这个问题了,到底什 ...

  4. 【javascript激增的思考03】MVVM与Knockout

    前言 今天搞的有点快,因为上午简单研究了下MVC,发现MVC不太适合前端开发,然后之前看几位前端前辈都推荐前端使用MVVM,但是我对其还不甚了解,所以我觉得下午还是应该先看看他是神马先,后面再决定要不 ...

  5. 深入了解Javascript模块化编程

    本文译自Ben Cherry的<JavaScript Module Pattern: In-Depth>.虽然个人不太认同js中私有变量存在的必要性,但是本文非常全面地介绍了Javascr ...

  6. Javascript模块化编程详解

    在这篇文章中,我将会回顾一下js模块化编程的基础,并且将会讲到一些真的非常值得一提的进阶话题,包括一个我认为是我自创的模式. 模块化编程是一种非常常见Javascript编程模式.它一般来说可以使得代 ...

  7. Javascript模块化编程(三):require.js的用法

    Javascript模块化编程(三):require.js的用法 原文地址:http://www.ruanyifeng.com/blog/2012/11/require_js.html 作者: 阮一峰 ...

  8. Javascript模块化编程(二):AMD规范

    Javascript模块化编程(二):AMD规范   作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_d ...

  9. Javascript模块化编程(一):模块的写法

    Javascript模块化编程(一):模块的写法 作者: 阮一峰 原文链接:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html ...

随机推荐

  1. .Net Request.Form含有危险字符的处理办法

    今天我们的网站遇到一个问题,下标就类似于化学分子式这样的是需要用"<sub></sub>"这个标签括起来的,当时没有转义,有部分标签就显示不出来了, 后来我 ...

  2. [转载]基于TFS实践敏捷-实现用户场景

    您是新用户的 Visual Studio 应用程序生命周期管理 (ALM) 和 Team Foundation Server (TFS) 吗? 您想知道如何您和您的团队可以获得最大受益的这些工具来生成 ...

  3. emacs: 文本输入中文件目录自动补全

    emacs: 文本输入中文件目录自动补全 // */ // ]]> UP | HOME   emacs: 文本输入中文件目录自动补全 Table of Contents 1 引言 2 补全过程演 ...

  4. Android中Services之异步IntentService

    IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务. IntentService有以下特点: (1)  它创 ...

  5. IIS 服务器下载apk文件报404错

    文件路径什么都对,可就是提示404错误,最后问题出在了IIS的MIME上,按照下面的办法即可解决. 1.在 IIS 管理器中,右键单击要为其添加 MIME 类型的网站或网站目录,单击"属性& ...

  6. Javascript动画效果(一)

    Javascript动画效果(一) 前面我们介绍了Javascript的回到顶部效果,今天呢,我们对Javascript动画做进一步的研究.在这篇博文中我们只介绍简单的匀速运动.简单的缓冲运动和简单的 ...

  7. 语义化HTML:ul、ol和dl

    一.语义化元素   1. ul标签 W3C草案: The ul element represents an unordered list of items; that is, a list in wh ...

  8. 【读书笔记】--SQL基础概念复习

    主键:每个表,只能有一个主键,主键不能为NULL,且必须是唯一的.主键最好是由单个列组成,但这不是必须的,主键也可以是由多个列组成,如果表的两个列组合在一起能唯一标识一个行,而单个列不能,则可以将这两 ...

  9. Windows Phone 8.1中AppBarToggleButton的绑定问题

    在WP8.1中,应用栏按钮已经可以支持绑定了,而且提供了一种AppBarToggleButton类型,相当于一种开关按钮,这种按钮有一个属性IsChecked,标记是否为选中状态. 于是想当然的,将I ...

  10. HoverTree项目已经实现分层

    HoverTree项目已经初步实现分层,源代码已经上传到 http://hovertree.com/down/ 请到SOURCE CODE查看. 在本地用SQL Server 2008 数据库测试成功 ...