MVC 和定名空间
要确保运用中的视图、状况和数据相互清楚星散,才能让架构越发整齐有序且越发硬朗。模子应该从视图和控制器中解耦出来。与数据操作和行动相干的逻辑都应该放入模子中,经由过程定名空间
举行治理。
在JavaScript 中,经由过程给对象增添属性来治理一个定名空间,这个定名空间可所以函数,也可所以变量,比方:
var User = {
records: [ /* ... */ ]
};
User
的数组数据就在定名空间User.records
中。和user 相干的函数也能够放入User 模子的定名空间里。比方用fetchRemote()
函数来从效劳器端猎取user 的数据:
var User = {
records: [],
fetchRemote: function(){ /* ... */ }
};
将模子的属性保留至定名空间中的做法能够确保不会发生争执,这也是相符MVC 准绳的,同时也能防止代码变成一堆函数和回调混淆在一起的大杂烩。
能够对定名空间做一点革新,将那些在实在user 对象上的和user 实例相干的函数也都增添进去。假定user 纪录包括一个destory()
函数,它是和详细的user 相干的,因而这个函数应该基于User 实例举行挪用:
var user = new User;
user.destroy()
为了做到这一点,应该将User 写成一个类,而不是一个简朴对象:
var User = function(atts){
his.attributes = atts || {};
};
User.prototype.destroy = function(){
/* ... */
};
关于那些和详细的user 不相干的函数和变量,则能够直接定义在User 对象中:
User.fetchRemote = function(){
/* ... */
};
构建对象关联映照(ORM)
对象关联映照(Ojbect-relational mapper,简称ORM)是在除JavaScript 之外的编程言语中常见的一种数据结构。在JavaScript 运用中,对象关联映照也是一种异常有效的手艺,它能够用来做数据治理及用做模子。比方运用ORM 能够将模子和长途效劳绑缚在一起,任何模子实例的转变都邑在背景提议一个Ajax 要求到效劳器端。或许将模子实例和HTML 元素绑定在一起,任何对实例的变动都邑在界面中反应出来。
如今让来建立一个自定义ORM。
本质上讲,ORM 是一个包装了一些数据的对象层。以往ORM 常用于笼统SQL 数据库,但在这里ORM 只是用于笼统JavaScript 数据类型。这个分外的层有一个优点,能够经由过程给它增添自定义的函数和属性来加强基本数据的功用。比方增添数据的合法性考证、监听、数据耐久化及效劳器端的回调处置惩罚等,如许会增添代码的重用率。
原型继续
这里运用Object.create()
来组织ORM,这里运用基于原型(prototype-based)的继续,而没有效到组织函数和new关键字。
Object.create()
只要一个参数即原型对象,它返回一个新对象,这个新对象的原型就是传入的参数。换句话说,传入一个对象,返回一个继续了这个对象的新对象。
关于不支持的Object.create()
的浏览器 ,能够很容易地模拟出这个函数:
if (typeof Object.create !== "function")
Object.create = function(o) {
function F() {}
F.prototype = o;
return new F();
};
如今来建立Model 对象,Model 对象将用于建立新模子和实例:
var Model = {
inherited: function(){},
created: function(){},
prototype: {
init: function(){}
},
create: function(){
var object = Object.create(this);
object.parent = this;
object.prototype = object.fn = Object.create(this.prototype);
object.created();
this.inherited(object);
return object;
},
init: function(){
var instance = Object.create(this.prototype);
instance.parent = this;
instance.init.apply(instance, arguments);
return instance;
}
};
create() 函数返回一个新对象,这个对象继续自Model 对象,运用它来建立新模子。
init() 函数返回一个新对象,它继续自Model.prototype——如Model 对象的一个实例:
var Asset = Model.create();
var User = Model.create();
var user = User.init();
增添ORM 属性
如今假如给Model 对象增添属性,关于继续的模子来讲,这些新增属性都是可接见的:
// 增添对象属性
jQuery.extend(Model, {
find: function(){}
});
// 增添实例属性
jQuery.extend(Model.prototype, {
init: function(atts) {
if (atts) this.load(atts);
},
load: function(attributes){
for(var name in attributes)
this[name] = attributes[name];
}
});
jQuery.extend() 只是替代for 轮回手动复制属性的一种快捷方式,这和在load()
函数中的做法差不多。如今,对象和实例属性都流传到了零丁的模子里:
assertEqual( typeof Asset.find, "function" );
实际上我们会增添许多属性,因而还需将extend() 和include() 增添至Model 对象中:
var Model = {
/* ……代码片断……*/
extend: function(o){
var extended = o.extended;
jQuery.extend(this, o);
if (extended) extended(this);
},
include: function(o){
var included = o.included;
jQuery.extend(this.prototype, o);
if (included) included(this);
}
};
// 增添对象属性
Model.extend({
find: function(){}
});
// 增添实例属性
Model.include({
init: function(atts) { /* ... */ },
load: function(attributes){ /* ... */ }
});
如今能够建立新的资本并设置一些属性:
var asset = Asset.init({name: "foo.png"});
【公然纪录进修JS MVC,不知道能对峙多久= =。以《基于MVC的JavaScript web富运用开辟》为重要进修材料。】