backbond Model实现
backbond中的M,指的是模型,即存放数据以及数据相关逻辑的单位。在分析其结构之前,先看一下其调用过程。
<script>
(function ($) {
World = Backbone.Model.extend({
initialize: function(){
alert('Hey, you create me!');
},
defaults: {
name:'张三',
age: '38'
}
});
var wodld = new World({x:1});
var x = new World({y:2});
})(jQuery);
backbond 通过Backbone.Model.extend方法得到一个World类(为了不让World和其实例化结果混淆,这里把World称为类,实例化结果称为对象),再通过实例化World来获得实例对象,并调用类中的initialize方法。这看起来和java很相似,也就是一种面向对象的编程方法。
在前面的backbond架构分析中,我们知道Backbone.Model.extend就是extend函数,从extend入手分析,先看一下extend在内部的实现。
var extend = function(protoProps, staticProps) {
var parent = this;
var child;
// 如果传入的对象中存在属性为construtor,那么将其构造函数作为child
// 否则,child作为一个调用父类的方法
if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
// 调用underscore的extend方法 将传入的第二个参数添加进child
_.extend(child, parent, staticProps);
// 对原型链进行设置 通过创建一个surrogate来使得child的原型链获得parent原型链
// 如果直接赋值 即child.prototype = parent.prototype,那么对child.prototype的改造也会影响到parent.prototype
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// 最后,由于上面的改造原型链,需要将child的上一层原型改为parent
child.__super__ = parent.prototype;
return child;
};
在extend中,最后返回的是一个函数,也就是上面例子中的World类,extend中的parent也就是Backbone.Model,即使得返回的函数的原型上具有Model和我们传入的属性。
接下来就是Model函数了,
var Model = Backbone.Model = function(attributes, options) {
//设置属性
var attrs = attributes || {};
options || (options = {});
this.cid = _.uniqueId('c');
this.attributes = {};
if (options.collection) this.collection = options.collection;
if (options.parse) attrs = this.parse(attrs, options) || {};
attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
this.set(attrs, options);
this.changed = {};
//调用initialize函数
this.initialize.apply(this, arguments);
};
我们知道,在js中使用new字符调用一个函数时,也就是创建了一个对象,this指向了这个对象并使该对象继承了构造函数的原型链,最后如果返回结果不是一个对象的话就返回这个对象。
那么在上面的例子中,最后通过了var world = new World({x:1});调用了World类,
而一开始我们在构造World类时并没有传入具有属性为constructor的对象,也就是说 World = function(){ return BackBond.Model.apply(this, arguments); };
其中的this就是新创建的对象,那么就在新创建的对象下调用了Backbond.Model,最后返回了这个对象,也就是我们上面的world对象。
最后我们在调试器打印出world对象。

最后,总结一下backbond具体的设计思路:
1: 定义Model函数,并在其原型上设置一系列方法。
2.1: 通过extend函数,获得一个函数(也就是我们创建的类),其原型继承了Model函数原型
2.2: 并根据我们传入的参数设置类为一个构造函数或者通过apply将上下文设置为我们的实例化对象来调用Model函数的函数(即初始化,并调用initlize函数,相当于java的构造函数)。
2.3: 最后返回类。
3: 实例化父类,获得对象。
这样的设计最终会使得我们像使用面向对象语言一样来使用Js。(类,构造函数,对象,继承...)。
backbond Model实现的更多相关文章
- backbond Model方法(set)
backbond的Model,其中存在一些操作属性的方法,而在这些方法中,最重要的就是set方法,其余的方法大部分都基于这个方法实现的,在backbond开发版中,也说了该方法是model中的核心方法 ...
- Spring Boot笔记一
Spring Boot 入门 Spring Boot 简介 > 简化Spring应用开发的一个框架:> 整个Spring技术栈的一个大整合:> J2EE开发的一站式解决方案: 微服务 ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- 详解树莓派Model B+控制蜂鸣器演奏乐曲
步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 拨开迷雾,找回自我:DDD 应对具体业务场景,Domain Model 到底如何设计?
写在前面 除了博文内容之外,和 netfocus 兄的讨论,也可以让你学到很多(至少我是这样),不要错过哦. 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领 ...
- 使用mybatis-generator在自动生成Model类和Mapper文件
使用mybatis-generator插件可以很轻松的实现mybatis的逆向工程,即,能通过表结构自动生成对应的java类及mapper文件,可以大大提高工作效率,并且它提供了很多自定义的设置可以应 ...
- “RazorEngine.Templating.TemplateParsingException”类型的异常在 RazorEngine.NET4.0.dll 中发生,但未在用户代码中进行处理 其他信息: Expected model identifier.
这个问题是由于在cshtml中 引用了model这个单词 它可能和Model在解析时有冲突. 解决方法:把model换成别的单词就可以了.
随机推荐
- orm介绍
昨日回顾: 1 今日内容: 1 orm介绍 1 tools--->Run manage.py Task python3 manage.py makemigrations 只需要敲命令:makem ...
- 交叉编译ffmpeg(hi3520d)
./configure \--prefix=/usr/local/ffmpeg-3520D \--cross-prefix=/opt/hisi-linux-nptl/arm-hisiv100-linu ...
- Prometheus Alert Rules with Some Metrics
Using Prometheus as a monitor system, it is quite efficent. The most important one is that alert tem ...
- 20145232韩文浩 《网络对抗技术》 Web基础
Apache 因为端口号80已经被占用(上次实验设置的),所以先修改/etc/apache2/ports.conf里的端口为5232后重新开启 可以在浏览器中输入localhost:5208来检查是否 ...
- Borg, Omega, and Kubernetes读后笔记
前言 最近又读了一遍 Borg, Omega, and Kubernetes 这篇文章,觉得这个文章写得很好,让我对架构设计有了进一步的认识,所以想写一篇读后笔记. 原文地址,还有篇中文翻译的,这个中 ...
- 项目小程序笔记-登录界面+FPGA管脚分配文件生成
声明:只是为了记录我遇到的一些问题,其中有我理解错的望勿参考. (1)qt designer设计好窗口 主窗口: 登录窗口: 关于qt designer的使用,大可以百度,很简单的,要注意的是部件的参 ...
- [转] IPTables for KVM Host
IPTables for KVM Host January 26, 2012 By Andrew Galdes Use the following IPTables rules “/etc/sysco ...
- 利用WindowsServiceWrapper(WinSW)将nginx包装为系统服务
1.WindowsServiceWrapper(WinSW) Github:https://github.com/kohsuke/winsw/ 下载地址:http://repo.jenkins-ci. ...
- [翻译][架构设计]The Clean Architecture
原文地址:The Clean Architecture The Clean Architecture Over the last several years we've seen a whole ra ...
- MySQL Schema与数据类型的优化
选择优化的数据类型: 1. 更小的通常更好: 一般情况下,应该尽量使用可以正确存储数据的最小数据类型.更小的数据类型通常更快,因为他们占用更少的磁盘,内存和cpu缓存,并且处理时需要的cpu周期也更少 ...