Skip to content

Instantly share code, notes, and snippets.

@lsmith
Created March 11, 2011 19:39
Show Gist options
  • Save lsmith/866445 to your computer and use it in GitHub Desktop.
Save lsmith/866445 to your computer and use it in GitHub Desktop.
Function to set up a lazy populating property on an object when possible. Getting the property value will do the value calculation, then remove the getter/setter, so it behaves like a normal property. Setting the property assigns the value and removes t
// Note o must be a DOM/COM object for IE8 to work. See below for a feature test for that.
var _define = (Object.defineProperty) ?
function (o, prop, fn) {
function val(v) {
var ret = (arguments.length) ? v : fn.call(this);
// delete needed for IE8
delete o[prop];
Object.defineProperty(o, prop, {
value: ret,
configurable: true,
writable: true
});
return ret;
}
Object.defineProperty(o, prop, {
get: val,
set: val,
configurable: true
});
} : ({}.__defineGetter__) ?
function (o, prop, fn) {
function val(v) {
// removes getter/setter
delete o[prop];
return (this[prop] = (arguments.length) ? v : fn.call(this));
}
o.__defineGetter__(prop, val);
o.__defineSetter__(prop, val);
} :
// FIXME: this will only decrease performance over separate setup logic that just
// calculates and assigned property values up front, so try to make sure the
// implementation logic never takes this path.
function (o, prop, fn) {
o[prop] = fn.call(o);
};
// Example
var someObject = {};
someObject.simpleProperty = 'Simple value. No need to delay this';
_define(someObject, 'complexProperty', function () {
FunInABox.open();
var thing1 = FunInABox.issueThing(),
thing2 = FunInABox.issueThing();
thing1.shakeHands();
thing2.shakeHands();
thing1.flyKiteIndoors();
thing2.flyKiteIndoors();
FunInABox.collect(thing1, thing2);
FunInABox.close();
return MyHouse.getState();
});
// Feature test to see if only IE8's level of support is available. Useful to see if you
// need to set up a proxy object.
var canUseIE8Support = (function () {
try {
Object.defineProperty({}, 'x', {});
} catch (ex1) {
try {
Object.defineProperty(document.createEventObject(), 'yes', {});
return true;
} catch (ex2) {}
}
return false;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment