81 lines
2.5 KiB
JavaScript
81 lines
2.5 KiB
JavaScript
// Original author: ClearCode Inc.
|
|
// License: MIT
|
|
// Repository: https://github.com/clear-code/js-extended-immutable
|
|
|
|
var EXPORTED_SYMBOLS = ['ExtendedImmutable'];
|
|
|
|
function ExtendedImmutable(aImmutable, aExtraProperties) {
|
|
var descriptors = {};
|
|
Object.keys(aExtraProperties).forEach(function(aName) {
|
|
descriptors[aName] = Object.getOwnPropertyDescriptor(aExtraProperties, aName);
|
|
});
|
|
|
|
var base = Object.create({}, descriptors);
|
|
return new Proxy(base, {
|
|
getPrototypeOf: function(aTarget) {
|
|
return Object.getPrototypeOf(aImmutable);
|
|
},
|
|
setPrototypeOf: function(aTarget, aPrototype) {
|
|
return Object.setPrototypeOf(aImmutable, aPrototype);
|
|
},
|
|
isExtensible: function(aTarget) {
|
|
return Object.isExtensible(aImmutable);
|
|
},
|
|
preventExtensions: function(aTarget) {
|
|
return Object.preventExtensions(aImmutable);
|
|
},
|
|
getOwnPropertyDescriptor: function(aTarget, aProperty) {
|
|
return Object.getOwnPropertyDescriptor(aImmutable, aProperty);
|
|
},
|
|
defineProperty: function(aTarget, aProperty, aDescriptor) {
|
|
return Object.defineProperty(aImmutable, aProperty, aDescriptor);
|
|
},
|
|
has: function(aTarget, aProperty) {
|
|
return aProperty in aImmutable;
|
|
},
|
|
get: function(aTarget, aName, aReceiver) {
|
|
if (descriptors.hasOwnProperty(aName)) {
|
|
let value;
|
|
if (typeof descriptors[aName].get == 'function')
|
|
value = descriptors[aName].get.call(base);
|
|
else
|
|
value = descriptors[aName].value;
|
|
|
|
if (typeof value == 'function')
|
|
return value.bind(base);
|
|
else
|
|
return value;
|
|
}
|
|
var value = aImmutable[aName];
|
|
if (typeof value == 'function')
|
|
return value.bind(aImmutable);
|
|
else
|
|
return value;
|
|
},
|
|
set: function(aTarget, aName, aValue, aReceiver) {
|
|
if (descriptors.hasOwnProperty(aName)) {
|
|
if (typeof descriptors[aName].set == 'function')
|
|
return descriptors[aName].set.call(base, aValue);
|
|
else
|
|
return descriptors[aName].value = aValue;
|
|
}
|
|
return aImmutable[aName] = aValue;
|
|
},
|
|
deleteProperty: function(aTarget, aProperty) {
|
|
delete aImmutable[aProperty];
|
|
},
|
|
enumerate: function(aTarget) {
|
|
return Reflect.enumerate(aImmutable);
|
|
},
|
|
ownKeys: function(aTarget) {
|
|
return Object.getOwnPropertyNames(aImmutable);
|
|
},
|
|
apply: function(aTarget, aThis, aArgs) {
|
|
return aImmutable.apply(aThis, aArgs);
|
|
},
|
|
construct: function(aTarget, aArgs) {
|
|
return new aImmutable(...aArgs);
|
|
}
|
|
});
|
|
}
|