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实现的更多相关文章

  1. backbond Model方法(set)

    backbond的Model,其中存在一些操作属性的方法,而在这些方法中,最重要的就是set方法,其余的方法大部分都基于这个方法实现的,在backbond开发版中,也说了该方法是model中的核心方法 ...

  2. Spring Boot笔记一

    Spring Boot 入门 Spring Boot 简介 > 简化Spring应用开发的一个框架:> 整个Spring技术栈的一个大整合:> J2EE开发的一站式解决方案: 微服务 ...

  3. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  4. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  5. 详解树莓派Model B+控制蜂鸣器演奏乐曲

    步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...

  6. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  7. 拨开迷雾,找回自我:DDD 应对具体业务场景,Domain Model 到底如何设计?

    写在前面 除了博文内容之外,和 netfocus 兄的讨论,也可以让你学到很多(至少我是这样),不要错过哦. 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领 ...

  8. 使用mybatis-generator在自动生成Model类和Mapper文件

    使用mybatis-generator插件可以很轻松的实现mybatis的逆向工程,即,能通过表结构自动生成对应的java类及mapper文件,可以大大提高工作效率,并且它提供了很多自定义的设置可以应 ...

  9. “RazorEngine.Templating.TemplateParsingException”类型的异常在 RazorEngine.NET4.0.dll 中发生,但未在用户代码中进行处理 其他信息: Expected model identifier.

    这个问题是由于在cshtml中 引用了model这个单词  它可能和Model在解析时有冲突. 解决方法:把model换成别的单词就可以了.

随机推荐

  1. iOS 数据归档----温故而知新

    #import "StudyViewController.h" #import "person.h" @interface StudyViewControlle ...

  2. 水晶报表使用IEnumerable<T>数据源

    这篇我们学习水晶报表,报表呈现的数据源是IEnumerable<T>.比如下面的数据: using System; using System.Collections.Generic; us ...

  3. 大叔学ML第一:梯度下降

    目录 原理 实践一:求\(y = x^2 - 4x + 1\)的最小值 实践二:求\(z = x^2 + y^2 + 5\)的最小值 问答时间 原理 梯度下降是一个很常见的通过迭代求解函数极值的方法, ...

  4. Laravel 5.6: Specified key was too long error

    Laravel 5.6: Specified key was too long error 在Laravel执行以下命令: php artisan migrate 这是由于Laravel5.6设置了数 ...

  5. 1.ActionBar

    ActionBar低版本和高版本用法不同 低版本:1. 引用v7-appcompat2. Activity继承ActionBarActivity3. android:theme="@styl ...

  6. Django项目配置日志

    LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': ...

  7. 吴恩达机器学习笔记24-神经网络的模型表示1(Model Representation of Neural Network I)

    神经网络模型建立在很多神经元之上,每一个神经元又是一个个学习模型.这些神经元(也叫激活单元,activation unit)采纳一些特征作为输出,并且根据本身的模型提供一个输出.下图是一个以逻辑回归模 ...

  8. 第73节:Java中的HTTPServletReauest和HTTPServletResponse

    第73节:Java中的HTTPServletReauest和HTTPServletResponse HTTP协议 客户端与服务器端通讯的一种规则. request: 请求行 请求头 请求体 respo ...

  9. 把ajax包装成promise的形式(1)

    概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...

  10. 将double或则float类型保留小数

    DecimalFormat df=new DecimalFormat("0.0");//“0.00” df.format(price);