问题描述
=人Backbone.Model.extend({
默认值:{
名称:'胎儿',
年龄:0,
孩子:[]
},
初始化:功能(){
警报(欢迎来到这个世界上);
},
采纳:功能(newChildsName){
VAR children_array = this.get(孩子);
children_array.push(newChildsName);
this.set({孩子:children_array});
}
}); 变种人=新的Person({名:托马斯,年龄:67,儿童:['瑞恩']});
person.adopt(约翰Resig的');
VAR孩子= person.get(孩子); // ['瑞恩','约翰Resig的']
在这个例子中code,我们有:
children_array = this.get(孩子)
我想这将只是指向同一阵列中的内存(因此是O(1))。不过转念一想,这将是一个地板的设计,因为一个可以操纵的阵列,而无需使用this.set(),然后事件侦听器就不会开火。
所以我猜它(不知何故神奇地)复制阵列??
该怎么办?
编辑:我刚刚发现在骨干源$ C $ C实施https://github.com/documentcloud/backbone/blob/master/backbone.js (我已经贴在底部相关code)
获取回报:
收益this.attributes [ATTR]
所以这将只是指向内存权的同一阵列?因此,人们可能会改变,而无需使用集(阵列),这将是坏..?我是正确的?
得到:函数(ATTR){
返回this.attributes [ATTR]
}, //获取属性的HTML转义值。
逃跑:功能(ATTR){
VAR HTML;
如果(HTML = this._escapedAttributes [ATTR])返回HTML;
VAR VAL = this.get(attr)使用;
返回this._escapedAttributes [ATTR = _.escape(VAL == NULL''''+ VAL);
}, //如果属性包含的值不为空返回TRUE
//或不确定。
有:函数(ATTR){
返回this.get(attr)使用!= NULL;
}, //设置模型的属性散列的对象,射击`变除非`
//你选择沉默吧。
设置:功能(键,值,选项){
VAR ATTRS,ATTR,VAL; //同时处理`钥匙,value`和`{键:值}`式的论点。
如果(_.isObject(密钥)||键== NULL){
ATTRS =键;
选项=价值;
}其他{
的attrs = {};
ATTRS [关键] =价值;
} //提取属性和选项。
选择|| (选项= {});
如果返回此(ATTRS!);
如果(ATTRS的instanceof模型)ATTRS = attrs.attributes;
如果(options.unset)为(以ATTRS attr)使用ATTRS [ATTR] = 0无效; //运行验证。
(!this._validate(ATTRS,期权))如果返回false; //检查id`的`变化。
如果(this.idAttribute在ATTRS)this.id = ATTRS [this.idAttribute] VAR变化= options.changes = {};
VAR现在= this.attributes;
VAR逃脱= this._escapedAttributes;
VAR preV =该._ previousAttributes || {}; //对于每一个`set`属性...
对(在ATTRS ATTR){
VAL = ATTRS [ATTR] //如果新的和当前的值不同,记录更改。
如果(的isEqual _(现[ATTR],VAL)||(options.unset&安培;!&放大器; _.has(现,ATTR))){
删除逃脱[ATTR]
(options.silent this._silent:改变?)[ATTR] =真;
} //更新或删除当前值。
options.unset?现在可以删除[ATTR]:现在[ATTR = VAL; //如果新和previous值不同,记录更改。如果不,
//然后删除该属性的变化。
如果(!_。isEqual:方法(preV [ATTR],VAL)||(_.has(现,attr)使用!== _.has(preV,ATTR))){
this.changed [ATTR = VAL;
如果(options.silent!)this._pending [ATTR] =真;
}其他{
删除this.changed [ATTR]
删除this._pending [ATTR]
}
} //火`变`事件。
如果(options.silent!)this.change(选件);
返回此;
},
的文档接口实际上并不指定谁拥有数组引用,所以你是你自己在这里。如果你看一下实现,你会看到(像你一样)的 GET
刚刚返回直出的型号的内部属性参考code>。这能与不变类型(如数字,字符串和布尔值),但运行到与可变类型的问题,如数组:你可以很容易地改变一些事情,而不必骨干知道关于它的任何方式
骨干机型似乎意在牵制基本类型。
有三个原因叫设置
:
- 这就是接口规范说的事情。
- 如果你不叫
设置
,你不触发事件。 - 如果你不叫
设置
,你会绕过验证逻辑设置
了。
您只需要当你使用数组和对象值的工作要小心。
请注意,这种行为 GET
和设置
是一个实现细节和未来的版本中可能会得到关于如何聪明,他们处理非原始属性值。
与阵列的情况属性(为此事对象属性)实际上是比你差可能最初怀疑。当你说 m.set(P,V)
,骨干会不会考虑设置
是一个变化,如果 v === current_value_of_p
,所以如果你拉出来一个数组:
VAR一个= m.get(P);
然后修改它:
a.push(X);
和发回的:
m.set(P,A);
您不会从模型中获取一个改变
事件,因为 A === A
; 使用下划线的的与!== 但效果是在这种情况下是相同的。
例如,诈骗的这个简单的一点:
VAR M = Backbone.Model.extend({});
变种M =新的M({号码:[1]});
m.on('变',函数(){的console.log('改为')});的console.log('设置新的数组');
m.set('P',[2]);的console.log('更改,恕不集');
。m.get('P')推(3);的console.log('GET数组,变更,并重新设置');
VAR一个= m.get('P'); a.push(4); m.set('P',一);的console.log('GET数组,克隆它,改变它,将它设置');
A = _(m.get('P'))的clone()。 a.push(5); m.set('P',一);
产生两个改变
事件:一前一后第一个设置
和一个最后<$ C $之后C>设置。
演示:
如果你看看设置
你会发现,有对属性的一些特殊的处理是 Backbone.Model
秒。
这里的基本教训很简单:
这篇关于不Backbone.Models this.get()整个数组或点复制到内存中的同一阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!