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.prototypevar 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的上一层原型改为parentchild.__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。(类,构造函数,对象,继承...)。
转载于:https://www.cnblogs.com/Darlietoothpaste/p/6623231.html
backbond Model实现相关推荐
- Tesla Model汽车架构与FSD供应链
Tesla Model汽车架构与FSD供应链 特斯拉Model 3和Model Y平台架构 特斯拉model Y和Model 3 怎么做平台架构. 通过特斯拉透露的信息,Model 3 和 model ...
- 特斯拉Tesla Model 3整体架构解析(上)
特斯拉Tesla Model 3整体架构解析(上) 一辆特斯拉 Model 3型车在硬件改造后解体 Sensors for ADAS applications 特斯拉 Model 3型设计的传感器组件 ...
- OC实用转换model的工具
OC实用转换model的工具 说明 这是本人写的一个专门用来将json数据直接转换生成Model文件的工具,目的是为了让你从写Model文件的繁琐过程中解脱出来,提升效率以及减少出错的几率,工具的特点 ...
- 一起学WP7 XNA游戏开发(八. 让3d model动起来)
如何让3d model动起来,其实就是要给model的bone设置动作,这样整个model就会动起来了. 一.获取Bones 在fbx文件中可以看到所有bones的名称,这样就可以通过名称来获取到bo ...
- PyTorch加载模型model.load_state_dict()问题,Unexpected key(s) in state_dict: “module.features..,Expected .
希望将训练好的模型加载到新的网络上.如上面题目所描述的,PyTorch在加载之前保存的模型参数的时候,遇到了问题. Unexpected key(s) in state_dict: "mod ...
- 什么是php model类,thinkphp的自定义model类有什么作用?
请问,thinkphp的自定义model类有什么作用?如: <?php //自定义Modle类 namespace Home\Model; use Think\Model; class StuM ...
- 基于pytorch的模型压缩和模型剪枝Model Prune示例
神经网络和卷积神经网络的模型剪枝Model Prune 1,神经网络和卷积神经网络模型剪枝方法. 2,可指定剪枝率进行定向剪枝,并输出剪枝后参数统计和finetune. 3,支持MLP, Lenet, ...
- 三、概念数据模型CDM(Conceptual Database Model )
最后整理一下正确的是: 脚本1: .set_value(_First, true, new) .foreach_part(%Name%, "'#'") .if (%_First ...
- 在Caffe中调用TensorRT提供的MNIST model
在TensorRT 2.1.2中提供了MNIST的model,这里拿来用Caffe的代码调用实现,原始的mnist_mean.binaryproto文件调整为了纯二进制文件mnist_tensorrt ...
- TensorRT Samples: MNIST(serialize TensorRT model)
关于TensorRT的介绍可以参考: http://blog.csdn.net/fengbingchun/article/details/78469551 这里实现在构建阶段将TensorRT mod ...
最新文章
- iOS6.0下获取通讯录用户列表
- 使用Navicat创建数据库,外键出现错误ERROR 1005: Can't create table (errno: 121)
- Mono for android,Xamarin点击事件的多种写法
- 火狐浏览器工具栏/折叠菜单怎么设置?火狐浏览器工具栏/折叠菜单定制教程
- 国内CDH的MAVEN代理
- 信息安全完全参考手册之风险分析(第二章)
- nginx location 斜杠_斜杠青年 菲斯塔车主实录
- 指针常量和常量指针的区别
- css 3D 旋转 - Demo
- mybatis批量操作(批量查询,批量插入,批量更新)
- 【ps功能精通】6.钢笔工具
- Acwing动态规划1——背包问题
- 网页游戏外挂的设计与编写:QQ摩天大楼【三】(登陆准备-信息发送方式)
- 李开复:李飞飞是人工智能的“良心”
- bugku writeup(misc_1)
- Domain Generalization数据集整理
- 详解自监督发展趋势! 何恺明连获三年CVPR最高引用的秘诀是?
- Linux命令之测试网络连通状态ping
- iOS Charts库绘制曲线
- 【解决方案】云看大熊猫,动物园直播解决方案EasyNVR+EasyNVS如何玩转动物IP