| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 
 | function Struct () {var keys = Array.prototype.slice.call(arguments, 0),
 dataStore = {};
 
 this.get = {};
 this.set = {};
 
 keys.forEach(this.addProperty.bind(this, dataStore));
 
 
 this.addProperty = this.addProperty.bind(this, dataStore);
 this.equal = this.equal.bind(this, dataStore);
 this.dataStoresEqual = this.dataStoresEqual.bind(this, dataStore);
 this.instanceOf = this.instanceOf.bind(this, dataStore);
 }
 
 Struct.prototype = {
 
 compareValue: function (localDataStore, foreignDataStore, result, key) {
 return result && localDataStore[key] === foreignDataStore[key];
 },
 
 dataStoresEqual: function (localDataStore, foreignDataStore) {
 var localKeys = Object.keys(localDataStore),
 foreignKeys = Object.keys(foreignDataStore),
 
 compare = this.compareValue.bind(null, localDataStore, foreignDataStore),
 equalKeyCount = localKeys.length === foreignKeys.length;
 
 return equalKeyCount && localKeys.reduce(compare, true);
 },
 
 equal: function (localDataStore, foreignStruct) {
 return foreignStruct.dataStoresEqual(localDataStore);
 },
 
 containsKey: function (foreignStruct, result, key) {
 return result && typeof foreignStruct.get[key] === 'function';
 },
 
 instanceOf: function (localDataStore, foreignStruct){
 return Object.keys(localDataStore).reduce(this.containsKey.bind(this, foreignStruct), true);
 },
 
 mergeKey: function (updateObj, key) {
 this.set[key](updateObj[key]);
 },
 
 merge: function (updateObj) {
 var keysToMerge = Object.keys(updateObj);
 keysToMerge.forEach(this.mergeKey.bind(this, updateObj));
 return this;
 },
 
 
 accessorBase: function (dataStore, key) {
 return dataStore[key];
 },
 
 
 mutatorBase: function (dataStore, key, value) {
 dataStore[key] = value;
 return this;
 },
 
 
 
 addProperty: function (dataStore, key) {
 dataStore[key] = null;
 
 this.get[key] = this.accessorBase.bind(this, dataStore, key);
 this.set[key] = this.mutatorBase.bind(this, dataStore, key);
 
 return dataStore;
 }
 };
 
 |