Person = Backbone.Model.extend({ defaults: { name: 'Fetus', age: 0, children: [] }, initialize: function(){ alert("Welcome to this world"); }, adopt: function( newChildsName ){ var children_array = this.get("children"); children_array.push( newChildsName ); this.set({ children: children_array }); } }); var person = new Person({ name: "Thomas", age: 67, children: ['Ryan']}); person.adopt('John Resig'); var children = person.get("children"); // ['Ryan', 'John Resig']
В этом примере кода у нас есть:
дети _массив = this.get ("дети")
Я думал, что это просто укажет на тот же массив в памяти (и будет O (1 )). Однако тогда я подумал, что это будет пол дизайна, потому что можно манипулировать массивом без использования this.set (), и тогда прослушиватели событий не сработают.
Я предполагаю, что (каким-то волшебным образом )копирует массив??
http://backbonejs.org/#Model-set
Что происходит?
редактировать :Я только что нашел реализацию в исходном коде магистрали по адресуhttps://github.com/documentcloud/backbone/blob/master/backbone.js(Я вставил соответствующий код внизу)
Получить возврат:
return this.attributes[attr]
так что это будет просто указывать на тот же массив в памяти, верно? Таким образом, можно было бы изменить массив без использования набора (), и это было бы плохо..? я прав?
get: function(attr) { return this.attributes[attr]; }, // Get the HTML-escaped value of an attribute. escape: function(attr) { var html; if (html = this._escapedAttributes[attr]) return html; var val = this.get(attr); return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val); }, // Returns `true` if the attribute contains a value that is not null // or undefined. has: function(attr) { return this.get(attr) != null; }, // Set a hash of model attributes on the object, firing `"change"` unless // you choose to silence it. set: function(key, value, options) { var attrs, attr, val; // Handle both `"key", value` and `{key: value}` -style arguments. if (_.isObject(key) || key == null) { attrs = key; options = value; } else { attrs = {}; attrs[key] = value; } // Extract attributes and options. options || (options = {}); if (!attrs) return this; if (attrs instanceof Model) attrs = attrs.attributes; if (options.unset) for (attr in attrs) attrs[attr] = void 0; // Run validation. if (!this._validate(attrs, options)) return false; // Check for changes of `id`. if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; var changes = options.changes = {}; var now = this.attributes; var escaped = this._escapedAttributes; var prev = this._previousAttributes || {}; // For each `set` attribute... for (attr in attrs) { val = attrs[attr]; // If the new and current value differ, record the change. if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) { delete escaped[attr]; (options.silent ? this._silent : changes)[attr] = true; } // Update or delete the current value. options.unset ? delete now[attr] : now[attr] = val; // If the new and previous value differ, record the change. If not, // then remove changes for this attribute. if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) { this.changed[attr] = val; if (!options.silent) this._pending[attr] = true; } else { delete this.changed[attr]; delete this._pending[attr]; } } // Fire the `"change"` events. if (!options.silent) this.change(options); return this; },