javascript动态加载实现方法一


Posted in Javascript onAugust 22, 2012

现在也有很多JS动态加载的框架,比如In.js。但是这种并不是我想要的编写方式,我来说说我的想法。

先来一段java代码

import Biz.User; 
User u = new User(); 
u.show();

按流程就是导包、实例化、调用。

JS是做不了导包的,或者说代码意义上的导包,一般只是在页面上进行script标签的引入。
那么 先假设需要写成这样

Using("User"); 
var u = new User(); 
u.show();

那么,在JS里面可以实现吗?

来一句一句的分析,当然,前提是页面并不用script标签载入user.js,不然就没意义了。

第一句

Using("User");

为什么用Using,当然只是我的一个命名想法而已,可以联想一下C#,用的就是using,借来而已。

Using里面写入的当然是我需要的对象User,顾名思义,我当然写成Using("User")了。先不说内里是怎么实现的,起码思路是这样。
因为不能模拟关键字写成 Using User;这种起码我是做不到了。
第二句和第三句

var u = new User(); 
u.show();

很正常,就是很平常的实例化与函数调用,唯一不解的是User对象哪里来的?那么当然是第一句导包的时候导入的。

流程就是这么个流程,那么到底能不能实现,关键就在第一句话。也就是说,到底能不能导包成功,而且该怎么导包。

从script标签吸引灵感,对,异步加载所需要的js文件。
也就是说

Using("User");

相当于写了一句
<script type="text/javascript" src="user.js"></script>

现在这么看下来,这么做有意义吗?就为把script标签写成JS动态引入的?或者,只为少写几个字符?

当然不能,这么做毫无意义!那要怎么做?
先从效率来讲。
如果一个页面需要载入N多js文件的时候,如下

<script type="text/javascript" src="jquery.min.js"></script> 
<script type="text/javascript" src="view.js"></script> 
<script type="text/javascript" src="register.js"></script> 
<script type="text/javascript" src="validate.js"></script> 
<script type="text/javascript" src="user.js"></script> 
<script type="text/javascript" src="order.js"></script> 
<script type="text/javascript" src="type.js"></script>

等等等等。

是不是很吓人,那是相当吓人,而且后期维护需要很高的成本,有多少页面,可能就需要修改几个页面。那么,当页面只引入关键的几个js文件,其他文件都采用动态载入的方式呢?
比如我们只需要载入jquery文件,然后调用

$.getScript("user.js",function(){});

这样,我们就做到页面文件里面只需要引入
<script type="text/javascript" src="jquery.min.js"></script>

即可。
那么这种写法的坏处在哪里?看一段代码
$.getScript("user.js",function(){ 
$.getScript("order.js",function(){ 
$.getScript("type.js",function(){ 
$.getScript("validate.js",function(){ 
// and so on.. 
}); 
}); 
}); 
});

PS:用In.js的watch函数是可以避免这种情况产生的。这不在本博文的考虑范围了。

花眼吗?还愿意去对齐代码吗?即便有格式化工具,你还愿意将闭合括号与哪个$.getScript对应吗?当然不愿意。
那么,仿java的导包形式应声而出。

Using("User"); 
Using("Order"); 
Using("Type"); 
Using("Validate"); 
// and so on..

或者你愿意,你可以
Using("User","Type","Order","Validate",...);

写法问题 无所谓。当然我推荐使用第一种方法,清晰。

导包之后,所有的用法不需要任何嵌套,正常使用。

var u = new User(); 
var o = new Order(); 
// and so on..

但是会提出一个问题。假如异步的加载都在Using("XXX")的时候执行,那么
Using("User"); 
Using("Order"); 
Using("Type"); 
Using("Validate"); 
// and so on..

这一段我就需要异步载入4个文件,虽然是异步的,但是未免有些麻烦?而且需要创建4个链接。你愿意合并JS的话,也可以。而且,Using的时候我是不需要使用对象的,这个时候未免太浪费资源了?

至于这个问题,我的解决办法就是学习hibernate,延迟加载,按需加载。
那么怎么做呢?

Using("User");

这个时候肯定是不加载,不加载做什么?当然是返回一个mock,也就是模拟对象。给用户先用着,只有当用户真正需要使用这个对象的时候,再去加载所需的js。也就是说
Using("User"); // 这句话执行完毕之后会创建一个User对象,当时仅仅是个mock 
var u = new User(); // 这个时候用需要的是真实的User对象实例,就在这个时候去动态加载JS文件,并且返回已经实例化的User对象

大家都知道,异步加载是与当前运行的状态不冲突的,也就是说
var u = new User();

这句话执行之后,u是一个没有实际意义值的变量,而已。那么,怎么解决这个问题,我暂且想到的办法,只能是采用同步策略了。只有当js加载完毕,再去执行之后的js语句,这个地方有点遗憾,而且同步可能带来的浏览器假死,也是一个比较严重的问题,暂且不顾这些问题,希望以后能有更好的办法解决。

那问题出来了,这么做同步,有什么优势吗?
我不知道有什么优势,起码对比异步加载,应该没有劣势。比如正常的异步加载为

$.getScript("user.js",function(){ 
var u = new User(); 
});

单单执行这个语句,要执行到function,本质上也是等user.js加载完毕才会执行,那么对比
var u = new User();

理论上时间应该相当,因为都是等user.js加载完毕之后才执行的。

起码第二种看起来更像java式的代码,不必理会其他非业务相关的代码。

那么,怎么会知道需要的对象在什么地方,怎么加载进来?我能想到的就是模拟一个配置文件,为什么用配置文件,而不是像In.js用add函数或者其他框架的类似于register的函数,大概我只是想用配置文件,更像java,而且后期的修改起来也会更解耦一些吧。

Using.Config = { 
"User" : "/js/user" // 可以隐去.js 因为肯定是加载JS文件了 
}

整个思路大概就是这个样子,我在其基础上进行了一些约束,比如加入了命名空间
var u = new Using.Modules.User();

这样可以减少一些全局变量,而且有需要的话,可以插入一些所有对象可能都具有的共性,减少创建类时的重复编码。

当然,也还是支持不使用命名空间的。

为了解决这个约束的效力,加入了Class.create函数来进行类创建约束。

Using.Class.create("User",function(){ 
}).property({ 
}).static({ 
}).namespace(Using.Modules);

这里的大概意思就是

create(类名,构造函数)
property(类的属性)
static(类的静态属性)
namespace(命名空间)

引申到此,为何不加入MVC形式?
后来我发现,要MVC,那么几个类之间的动态维护,或者创建之时就由Using这个类来自动维护,暂时还没想到好的解决办法,所以没有加入其中,只能自己创建类,自己维护了.

通过上面的文字,最后得到一个Using.js
然后在页面里面就只需要引入一个

<script type="text/javascript" src="using.js"></script>

这样接下来就可以写
Using("jquery"); 
Using("User"); $("#ID").click(function(){ 
var user = new User(); 
user.name = "xx"; 
user.show(); 
});
Javascript 相关文章推荐
克隆javascript对象的三个方法小结
Jan 12 Javascript
关于JavaScript的面向对象和继承有利新手学习
Jan 11 Javascript
jquery获取tr中控件值并操作tr实现思路
Mar 27 Javascript
jQuery中获取Radio元素值的方法
Jul 02 Javascript
javascript中Number对象的toString()方法分析
Dec 20 Javascript
jQuery实现产品对比功能附源码下载
Aug 09 Javascript
轻松学习Javascript闭包
Mar 01 Javascript
Angularjs上传图片实例详解
Aug 06 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
Dec 25 Javascript
Vuex的初探与实战小结
Nov 26 Javascript
如何利用JavaScript编写更好的条件语句详解
Aug 10 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
Sep 22 Javascript
原生js写的放大镜效果
Aug 22 #Javascript
window.open不被拦截的实现代码
Aug 22 #Javascript
EASYUI TREEGRID异步加载数据实现方法
Aug 22 #Javascript
网页打开自动最大化的js代码
Aug 22 #Javascript
精心挑选的12款优秀的基于jQuery的手风琴效果插件和教程
Aug 22 #Javascript
eval的两组性能测试数据
Aug 17 #Javascript
javascript五图轮播切换实用版
Aug 17 #Javascript
You might like
《一拳超人》埼玉一拳下去,他们存在了800年毫无意义!
2020/03/02 日漫
浅析使用Turck-mmcache编译来加速、优化PHP代码
2013/06/20 PHP
thinkphp配置连接数据库技巧
2014/12/02 PHP
php+mysql实现用户注册登陆的方法
2015/01/03 PHP
php微信开发接入
2016/08/27 PHP
laravel框架 api自定义全局异常处理方法
2019/10/11 PHP
DOM相关内容速查手册
2007/02/07 Javascript
JavaScript 监听textarea中按键事件
2009/10/08 Javascript
用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数
2012/01/21 Javascript
用C/C++来实现 Node.js 的模块(一)
2014/09/24 Javascript
JavaScript中的toLocaleLowerCase()方法使用详解
2015/06/06 Javascript
基于js实现投票的实例代码
2015/08/04 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
2015/10/08 Javascript
javascript发送短信验证码实现代码
2015/11/12 Javascript
javascript html5实现表单验证
2016/03/01 Javascript
Move.js入门
2017/02/08 Javascript
微信小程序有旋转动画效果的音乐组件实例代码
2018/08/22 Javascript
在vue+element ui框架里实现lodash的debounce防抖
2019/11/13 Javascript
Vue中computed及watch区别实例解析
2020/08/01 Javascript
Python中摘要算法MD5,SHA1简介及应用实例代码
2018/01/09 Python
对django xadmin自定义菜单的实例详解
2019/01/03 Python
python如何实现不用装饰器实现登陆器小程序
2019/12/14 Python
Python集合操作方法详解
2020/02/09 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
Python通过zookeeper实现分布式服务代码解析
2020/07/22 Python
使用CSS3实现input多选框自定义样式的方法示例
2019/07/19 HTML / CSS
HTML5图片预览实例分享
2014/06/04 HTML / CSS
英国户外玩具儿童游乐设备网站:TP Toys(蹦床、攀爬框架、秋千、滑梯和游戏屋)
2018/04/09 全球购物
出纳岗位职责范本
2013/12/01 职场文书
财务经理的岗位职责
2013/12/17 职场文书
婚前财产协议书范本
2014/10/19 职场文书
追悼会悼词大全
2015/06/23 职场文书
文明礼仪主题班会
2015/08/13 职场文书
党员公开承诺书2016
2016/03/24 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle
Python中的套接字编程是什么?
2021/06/21 Python