Subj : Re: outer visibility of nested functions To : =?ISO-8859-1?Q?Georg_Maa=DF?= From : Brendan Eich Date : Sat Jan 10 2004 10:45 am Georg Maaß wrote: > Brendan Eich wrote: > >> There is, as needed (whenever A is activated). > > > js> function A() > { > function B() > { > print(this.name); > } > B.name = 'B'; BTW, SpiderMonkey has predefined f.name for function f() {} since long ago, so you don't need to do this if you're targeting only Mozilla or Netscape. > B(); > print(A.C); > var C = 'C'; > print(A.C + '\n'+ C); > } > js> A.C='c'; > c > js> A.C > c > js> A(); > global ECMA censors activation objects so they never bind to |this| -- instead, null is used, and when the object reference with a null base is evaluated, the "global object" is substituted for the null base. I think this was a big mistake. As Doug Crockford and many others have pointed out, it makes inner function |this| binding generally useless. It's years too late to fix, sad to say. > c > c > C > js> > > OK, I see. It is really independent for stuff like variables. Yes, per spec and sanity. > js> function A() > { > function B() > { > print(this.name); > } > B(); > A.B = 'boom'; > } > js> A.B(); > A > js> A(); > global > js> A.B > boah Eh? Did you mistype, not copy-and-paste? > js> A.B(); > 103: TypeError: A.B is not a function > js> > > A consequence of this extension is that calling A destroys the nested > function B. Only in your example, only because A sets A.B = 'boom', and 'boom' is not a function. This is a "do what I say" == "do what I mean" case, I think. > Is it possible to make this extention switchable at runtime i.e. by > implementing a boolean property > __mapNestedFunctionsAsFunctionPorperties__ in the function prototype to > enable or disable the extension as desired by the application? I don't see any point. More likely, if no one needs it, I'd remove the old dependency (which exists only at compile time) of the outer function object on the inner one being a named property of the outer. See the XXX comments at http://lxr.mozilla.org/mozilla/source/js/src/jsparse.c#871 (among other related XXX comments in the source). >> That follows the usual this-binding rule: callee expression object >> reference base. > > > Yes, if B is called by the body of A, then this points to the global > object. This is the only way to call B in NN4 NN4 preceded ECMA Edition 3, where all this was nailed down, if memory serves (possibly nested functions were better specified in Edition 2, but I do not believe NN4 ever contained anything beyond the more-or-less ECMA-262 Edition 1 plus JS1.2 extensions -- someone correct me if my old memory is failing). Are you targeting NN4 as well as more modern browsers with advanced JS? How is it going? /be .