から既存のインスタンスを返すことによって、JavaScriptのインスタンスストアを実装し、私は彼らの最近のブログ記事でてSoundcloudで説明したようBACKBONE.JSで「インスタンスストア」の私のバージョンを実装しようとしています:はコンストラクタ
http://backstage.soundcloud.com/2012/06/building-the-next-soundcloud/
関連抜粋:
これを解決するために、インスタンスストアと呼ばれる構造を使用します。このストアは、モデルのコンストラクタが呼び出されるたびに暗黙的にアクセスされ、変更されるオブジェクトです。モデルが初めて構築されると、そのモデルを固有のキーとしてIDを使用してストアに注入します。同じモデルコンストラクタが同じIDで呼び出された場合、元のインスタンスが返されます。
var s1 = new Sound({id: 123}),
s2 = new Sound({id: 123});
s1 === s2; // true, these are the exact same object.
これはJavascriptの驚くほど知られていない機能のために動作します。コンストラクタがオブジェクトを返す場合、それは割り当てられた値です。したがって、前に作成したインスタンスへの参照を返すと、目的の動作が得られます。舞台裏では、コンストラクタは、基本的にこれをやっている:
var store = {};
function Sound(attributes) {
var id = attributes.id;
// check if this model has already been created
if (store[id]) {
// if yes, return that
return store[id];
}
// otherwise, store this instance
store[id] = this;
}
私は自分のコンストラクタを作成するためにBackbone.Modelクラスをオーバーライドすることによって、この私のバージョンを実装しました。
var MyModel = Backbone.Model.extend({
constructor: function (attributes, options) {
var id = attributes ? attributes.id : undefined;
if (this.store[id]) {
return this.store[id];
}
Backbone.Model.prototype.constructor.apply(this, arguments);
if (id) {
this.store[id] = this;
}
}
});
var MyOtherModel = MyModel.extend({
store: {},
//other model stuff
});
これはうまくいきましたが、何かが変更されている必要があり、現在は動作が停止しています。新しく作成されたインスタンスは問題なしでストアオブジェクトに格納されます.MyModelクラスを拡張する各クラスは、同じIDを持つ異なる型のインスタンスの衝突を避けるために独自の空のストアを持っています。正しいインスタンスは、コンストラクターが既存のIDで呼び出されたときに問題なく検索されますが、コンストラクターから返されるときには戻り値は無視されます。仕様から私の理解は、コンストラクタが新しいオペレータで呼び出されたときに、コンストラクタがオブジェクトを返すことができますが、プリミティブは返すことができず、返されたオブジェクトは代入文の左辺に割り当てられます。これは起こらず、たとえコンストラクタがオブジェクトを返すとしても、new演算子で作成された空のオブジェクトが使用されます。
一部のデバッグ情報。この情報がどの程度役立つかはわかりません。これは、初めてインスタンス化されるオブジェクトのMyModelコンストラクタ内の「this」です。
child
_callbacks: Object
_escapedAttributes: Object
_previousAttributes: Object
_setting: false
attributes: Object
id: "4fd6140032a6e522f10009ac"
manufacturer_id: "4f4135ae32a6e52a53000001"
name: "Tide"
uniqueName: "tide"
__proto__: Object
cid: "c50"
collection: child
id: "4fd6140032a6e522f10009ac"
__proto__: ctor
constructor: function(){ parent.apply(this, arguments); }
defaults: Object
store: Object
url: function() {
urlRoot: function() {
__proto__: ctor
そして、これは「これは」mymodelというコンストラクタで、それは、インスタンスストアから返されるオブジェクトのときである:私は注意して何
child
_callbacks: Object
_escapedAttributes: Object
_previousAttributes: Object
_setting: false
attributes: Object
_validate: function (attrs, options) {
bind: function (events, callback, context) {
change: function (options) {
changedAttributes: function (diff) {
clear: function (options) {
clone: function() {
constructor: function(){ parent.apply(this, arguments); }
defaults: Object
destroy: function (options) {
escape: function (attr) {
fetch: function (options) {
get: function (attr) {
has: function (attr) {
hasChanged: function (attr) {
idAttribute: "id"
initialize: function(){}
isNew: function() {
isValid: function() {
manufacturer_id: 0
name: ""
off: function (events, callback, context) {
on: function (events, callback, context) {
parse: function (resp, xhr) {
previous: function (attr) {
previousAttributes: function() {
save: function (key, value, options) {
set: function (key, value, options) {
store: Object
toJSON: function() {
trigger: function (events) {
unbind: function (events, callback, context) {
unset: function (attr, options) {
url: function() {
urlRoot: function() {
__proto__: Object
cid: "c141"
__proto__: ctor
constructor: function(){ parent.apply(this, arguments); }
defaults: Object
store: Object
url: function() {
urlRoot: function() {
__proto__: ctor
は属性が二番目にオブジェクトということですしているすべてのそれらに含まれているバックボーンオブジェクトのメソッドです。それにもIDはありませんが、私は再びなぜわかりません。うまくいけば、これはいくつかの洞察を提供します。ありがとう。
あなたは私たちにDEBを与えることができますMyModelの眺めは? – Bergi
私の無知を許しても、あなたが必要とするものを正確に指定することはできますか? JavaScriptデバッギング初心者は、私のデバッグは一般的にconsole.logステートメントで構成されています。 – Kareem
はい、それは素晴らしいでしょう。私はそれが関数であり、そのコードと多分それがアクセスできる変数スコープが面白いと思います。 – Bergi