FWIW, here is the pattern that appears to work in JSFiddle for a "static var
foo":
o.get__foo = function() {
var value = <initializer expression>
Object.defineProperty(o, 'foo', {value : value, writable: true});
return value;
}
o.set__foo = function(value) {
Object.defineProperty(o, 'foo', {value : value, writable: true});
}
Object.defineProperties(o, { foo: { get: o.get__foo,set: o.set__foo,
configurable: true}})
We have to use Object.defineProperties in order to use an @lends JSDoc
annotation (not shown) for the minifier.
A similar pattern will be used for "static const foo":
o.get__foo = function() {
var value = <initializer expression>
Object.defineProperty(o, 'foo', {value : value, writable: false});
return value;
}
Object.defineProperties(o, { foo: { get: o.get__foo, configurable: true}})
Of course, I could be wrong...
-Alex
On 11/5/19, 8:56 AM, "Harbs" <[email protected]> wrote:
Good point on PAYG.
If we use #2 with one-time lazy evaluation, I think that’s the best of both
worlds.
Thanks,
Harbs
> On Nov 5, 2019, at 6:44 PM, Alex Harui <[email protected]> wrote:
>
> Yeah, in my local branch I'm playing with various ways to not run the
initializer more than once. We can tweak the pattern later. It involves
re-defining the property, but isn't quite the patterns offered below.
>
> IMO, #2 is more PAYG than #1. In #1, all initializers run regardless of
whether your code uses that value or not. In #2, the initializers run on
demand, which is actually somewhat more like the Flash runtime. AIUI, Flash
does not run a class's static initializers until the class is about to be
accessed by code. All initializers for a class then run, but if your code
never gets to the point where the verifier needs to verify the class, the
initializers are not run.
>
> -Alex
>
> On 11/4/19, 11:49 PM, "Greg Dove" <[email protected]> wrote:
>
> Yeah, in all cases where I had to do this manually I used a private
static
> backing var and populated it on first request similar to what is
typically
> done for singleton-like get accessors. Otherwise it's not really safe
> compared to the original (and as you say, could have performance issues
> too).
>
> On Tue, 5 Nov 2019, 20:31 Harbs, <[email protected]> wrote:
>
>> It seems to me that the getter approach can have an impact on
performance.
>> With approach #1, the static consts will only be evaluated once, while
with
>> #2, it will be evaluated every time it’s accessed.
>>
>> Maybe we could use a hybrid approach where “bar” is redefined as the
>> evaluated value the first time it’s accessed.
>>
>> Something like this:
>>
>> Foo.get__bar = function() {
>> var val = ResourceManager.getInstance().getString("baz");
>> delete Foo.bar;
>> Foo.bar = val;
>> return val;
>> Object.defineProperty(Foo, "bar", {get: Foo.get__bar});
>>
>> or maybe this:
>>
>> Foo.get__bar = function() {
>> var val = ResourceManager.getInstance().getString("baz");
>> // is delete needed?
>> delete Foo.bar;
>> Object.defineProperty(Foo, "bar", {get: function(){return val}});
>> return val;
>> }
>> Object.defineProperty(Foo, "bar", {get: Foo.get__bar});
>>
>>
>> Harbs
>>
>>> On Nov 5, 2019, at 2:52 AM, Alex Harui <[email protected]> wrote:
>>>
>>> Hi,
>>>
>>> The issue of complex static initializers and dependency order keeps
>> coming up. In reviewing the past discussions, there were a couple of
>> suggestions:
>>> 1) separate static initializers into a block of code that runs after the
>> class is defined
>>> 2) use getters
>>>
>>> I'm going to try #2. I'm not convinced #1 will work well with minifiers
>> or help us get the dependency order right.
>>>
>>> Thoughts? Is there a case where getters won't work?
>>>
>>> For:
>>>
>>> public class Foo {
>>> public static const bar:String =
>> ResourceManager.getInstance().getString("baz");
>>> }
>>>
>>> We currently generate:
>>>
>>> Foo.bar = ResourceManager.getInstance().getString("baz");
>>>
>>> And lots of other code tries to understand that the
>> goog.require("ResourceManager") is more important than other
goog.requires
>> in the remove-circulars dependency calculation.
>>>
>>> But if we generate:
>>> Foo.get__bar = function() { return
>> ResourceManager.getInstance().getString("baz");};
>>> Object.defineProperty(Foo, "bar", {get: Foo.get__bar});
>>>
>>> Then I think no statics will get evaluated at load time.
>>>
>>> Of course, I could be wrong...
>>> -Alex
>>>
>>
>>
>
>