Created
March 11, 2011 19:39
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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