BackboneJS框架的技巧及模式(1)
来源:互联网 发布:7u分享网络app 编辑:程序博客网 时间:2024/06/05 14:52
《BackboneJS框架的技巧及模式》(1)
原文见:http://coding.smashingmagazine.com/2013/08/09/backbone-js-tips-patterns/
译者注:本文采用意译,省略所有口水话,内容直指要义。
作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs
BackboneJS是一个流行的JavaScript MVC/MVVM框架,第一版发布于三年多前,到现在已经是一个颇有影响力的框架。尽管BackboneJS提供了JavaScript项目的基本结构,但它还留下了很多设计模式和决策供开发者使用。
因此,本文会介绍很多不同的设计模式供BackboneJS开发过程中使用,还会介绍一些开发中可能遇到的陷阱。
应用就和建筑一样,都是遵循已知的模式进行构建。
一、实现对象的深度复制
JavaScript把所有的原生类型变量都以值传递的方式对待。因此,当原生类型的变量被引用时,变量的值会被传递。
比如,上面代码中,设置helloWorldCopy变量的值等同于helloworld变量。因此,任何修改变量helloWorldCopy值的行为并不会影响到helloWorld变量,因为这是一份拷贝。
JavaScript把所有的非原生类型的变量都以参数传递的方式对待。这意味着当非原生类型的变量被引用时,JavaScript会传递变量的内存地址。
var helloWorld = { ‘hello’: ‘world’}var helloWorldCopy = helloWorld;
比如,上面的代码设置helloWorldCopy变量的值等同于helloworld变量的引用。当修改helloWorldCopy变量时,会直接操纵helloWorld变量。而如果你想拥有一份helloWorld的拷贝,那么你必须创建对象的拷贝。
你或许会想到这样的问题,“为什么BackboneJS中到处都是引用传递?”
BackboneJS并不会复制对象,这意味着如果你从模型调用.get()方法获得一个对象,任何对此对象的修改都会直接修改原对象。
下面我们一起看一个例子来说明此问题。如果你有如下的Person模型:
var Person = Backbone.Model.extend({ defaults: { 'name': 'John Doe', 'address': { 'street': '1st Street', 'city': 'Austin', 'state': 'TX', 'zipCode': 78701 } }});
接着我们创建了一个新person对象:
var person = new Person({ 'name': 'Phillip W'});
接下来我们操纵新person对象的一些属性:
person.set('name', 'Phillip W.', { validate: true });
上面的代码成功地修改了person对象的name属性。接着,我们试着修改person对象的address属性。但是,在做之前,我们先验证一下地址属性:
var Person = Backbone.Model.extend({ validate: function(attributes) { if(isNaN(attributes.address.zipCode)) return "Address ZIP code must be a number!"; }, defaults: { 'name': 'John Doe', 'address': { 'street': '1st Street', 'city': 'Austin', 'state': 'TX', 'zipCode': 78701 } } });
接着,我们尝试用错误的ZIP代码设置地址:
var address = person.get('address');address.zipCode = 'Hello World';// Raises an error since the ZIP code is invalidperson.set('address', address, { validate: true });console.log(person.get('address'));/* Prints an object with these properties.{ 'street': '1st Street' 'city': 'Austin', 'state': 'TX' 'zipCode': 'Hello World'}*/
这会怎么样呢?我们的验证出现了错误!为什么属性依旧被修改了?正如前面提过的,BackboneJS不会复制模型的属性,它只会简单地返回你所请求的一切。因此,如你所料,如果你请求一个对象,你会得到此对象的引用。对此对象的任何操作都会直接改变模型中的实际对象。
如果你要debug,这可能将把你带入到无底的兔子黑洞。
实现一个深度模型对象的复制可能会让你在调试中避免掉入兔子洞。
此问题对于BackboneJS新手要引起注意,甚至一些JavaScript老手也该提防。
在这里:https://github.com/documentcloud/backbone/issues/2315有深度的讨论。
正如Jeremy Ashkenas所说,实现深度复制是用于解决不同的问题,尤其是在很大、有深度的对象来说,此操作的内存开销很大。
幸运的是,jQuery库提过了一个深度复制的实现,即$.extend操作。顺便说一句,UnderscoreJS框架(它依赖于BackboneJS),也提供了_.extend这样的函数,但是我们应该尽量避免使用它,因为它没有实现深度复制。
Lo-Dash (http://lodash.com/)是UnderscoreJS的分支和优化版本,提供了_.clone函数,实现了深度复制。但是,我使用$.extend来实现任意对象的深度复制,对象是通过.get()从模型中获取的。记住要传递true,它指示执行对象的深度复制。
var address = $.extend(true, {}, person.address);
我们现在有address对象的准确复制了,我们可以随心修改内容而无需担心修改了实际的模型。要注意一点,此模式工作的前提是由于address对象的所有成员变量都是不可变 的(数字或字符串等)。还要注意,深度复制对性能是有一点儿影响的,尤其是对于大对象来说。
- BackboneJS框架的技巧及模式(1)
- 《BackboneJS框架的技巧及模式》(2)
- 《BackboneJS框架的技巧及模式》(3)
- 《BackboneJS框架的技巧及模式》(4)完结篇
- 史上最全的APP推广模式及方法技巧
- Struts 框架的基本概念及实现MVC模式的原理
- Struts 框架的基本概念及实现MVC模式的原理
- 架构设计模式及框架
- 开发模式及框架梳理
- BackboneJs入门学习[03]—Model实践(1)
- backbonejs mvc
- 三大JavaScript框架对比——AngularJS、BackboneJS和EmberJS
- HTML框架应用的技巧
- 集合框架的阅读技巧
- iOS设计模式的学习记录 (1) --- 框架模式MVC
- Reactor构架模式及框架概述
- 深入理解IOC模式及Unity框架
- Reactor构架模式及框架概述
- 根据前序跟中序遍历的结果建立二叉树——迭代和递归的方法
- 豆瓣客户端(三)发送图文广播
- 快速幂-poj3641
- 介绍一个牛人的机器学习PPT
- 初始化参数文件
- BackboneJS框架的技巧及模式(1)
- Blender学习笔记10.2
- C++内存模型
- Android开发优化之——对界面UI的优化
- 复杂的Singleton
- C++中String类的截取字符串学习笔记
- 八皇后问题,求解的个数
- 最小不重复数(百度笔试题)
- Android开发优化之——从代码角度进行优化