Prev: How do I get keys from an associative array?
Next: instructor's solutions manual for Basic Electromagnetics with Applications by Nannapaneni Narayana Rao
From: Stoyan on 20 Feb 2010 21:37 Hi group, Since JS is everywhere (client, server, desktop...), it makes sense to think how to write code that could run in environments other than the one originally in mind. Perhaps it's not a good idea to use `window` when the code could possibly run in environment that has no idea what `window` is. so this pattern came to mind: var global = function(){return this;}(); However this apparently won't work in ES5 strict which aims to prevent errors from calling constructors without `new` Another hacky idea is to call a function that assumes global when `this` is unusable. Andrea Giammarchi came up with the shortest form (http://twitter.com/WebReflection/status/9406207674) var global = [].sort.call(null); The question is - is that ES5 strict-safe? Or any other ideas how to get access to the global without hardcoding its name? Of course alternatively the new environment could simply define window and problem is solved. E.g. if in some environment the global object is called `foo`, then just do a global var window = foo; and call it a day :) Thoughts? Thanks, Stoyan
From: Thomas 'PointedEars' Lahn on 20 Feb 2010 22:13 Stoyan wrote: > Since JS is everywhere (client, server, desktop...), it makes sense to > think how to write code that could run in environments other than the > one originally in mind. Perhaps it's not a good idea to use `window` > when the code could possibly run in environment that has no idea what > `window` is. Sigh. [psf 10.1] It has *never* been a good idea to use a proprietary, host-defined property, that is supposed to refer to a host object to access a different, standardized, native object. But some people just would not listen. > so this pattern came to mind: > var global = function(){return this;}(); > However this apparently won't work in ES5 strict which aims to prevent > errors from calling constructors without `new` Have you seen a single conforming implementation of ES5, in particular have you seen a widely distributed one that supports strict mode yet? If yes, which one? If no, why bother now? (JFYI: It took almost 10 years for ES3F to be widely implemented. Why do you expect ES5 to be any faster?) Besides, I doubt this has anything to do with constructors. > Another hacky idea is to call a function that assumes global when > `this` is unusable. Andrea Giammarchi came up with the shortest form > (http://twitter.com/WebReflection/status/9406207674) > var global = [].sort.call(null); Very efficient; very compatible, too. NOT. > The question is - is that ES5 strict-safe? Read the Specification for yourself (for a change). Ask smart questions here if anything you read is still unclear. > Or any other ideas how to get access to the global without hardcoding > its name? What exactly do you mean by "the global"? > Of course alternatively the new environment could simply define window > and problem is solved. What hypothetical new environment are you talking about? Why should any non-browser environment implement a property that only makes sense in a browser environment? > E.g. if in some environment the global object is called `foo`, Objects do not have names, they have an identity each. > then just do a global var window = foo; and call it a day :) > > Thoughts? var _global = this; in the global execution context. (In my JSX since quite a few years. Newer versions introduced `jsx.global' as in-library reference -- locally aliased to jsx_global where reasonable -- to avoid possible incompatibilities with other libraries.) Do you realize that this is recommended literally on the first page of the Core JavaScript 1.5 Reference? PointedEars -- var bugRiddenCrashPronePieceOfJunk = ( navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1 ) // Plone, register_function.js:16
From: Stoyan on 20 Feb 2010 23:00 Thanks Thomas! > Have you seen a single conforming implementation of ES5, in particular have > you seen a widely distributed one that supports strict mode yet? If yes, > which one? If no, why bother now? (JFYI: It took almost 10 years for ES3F > to be widely implemented. Why do you expect ES5 to be any faster?) Good point. But we can hope :) > > Another hacky idea is to call a function that assumes global when > > `this` is unusable. Andrea Giammarchi came up with the shortest form > > (http://twitter.com/WebReflection/status/9406207674) > > var global = [].sort.call(null); > > Very efficient; very compatible, too. NOT. You're right. Not Andrea's fault, he just make my clumsy version much shorter. What I had was worse: var global = function(){var x;return(x=[].sort)()}(); > Read the Specification for yourself (for a change). Ask smart questions > here if anything you read is still unclear. Thanks, I'll ask :) > > > Or any other ideas how to get access to the global without hardcoding > > its name? > > What exactly do you mean by "the global"? > I meant "the global object" > > Of course alternatively the new environment could simply define window > > and problem is solved. > > What hypothetical new environment are you talking about? Why should any > non-browser environment implement a property that only makes sense in a > browser environment? > What I had in mind was - say you're building a library and it's so useful it makes sense to use the same library in other environments, not only the browser. For example you can do server-side scripts or write photoshop scripts. The photoshop environment for example doesn't have `window`, but it does have a global `app`. In such cases when you use a library which uses `window` to refer to the global object, you can probably do var window = this; and the library should work > > Thoughts? > > var _global = this; > > in the global execution context. > I was thinking about when not in the global context? Say your library has a function and inside that function you want check the global namespace for something. Probably to far-fetched case, I don't know. I guess a good approach for a library is to store a global reference for future internal use, just like you suggested. var MyLib = function() { // my whole lib is here, // no other global vars leaked return { someMethod: function() { var g = MyLib._global; //... } }; }(); MyLib._global = this; This way someMethod() doesn't need to figure out access to the global object on its own. Thanks again for your reply! Stoyan > (In my JSX since quite a few years. Newer versions introduced `jsx.global' > as in-library reference -- locally aliased to jsx_global where reasonable > -- to avoid possible incompatibilities with other libraries.) > > Do you realize that this is recommended literally on the first page of the > Core JavaScript 1.5 Reference? > > PointedEars > -- > var bugRiddenCrashPronePieceOfJunk = ( > navigator.userAgent.indexOf('MSIE 5') != -1 > && navigator.userAgent.indexOf('Mac') != -1 > ) // Plone, register_function.js:16
From: David Mark on 20 Feb 2010 23:09 Stoyan wrote: > Hi group, > > Since JS is everywhere (client, server, desktop...), it makes sense to > think how to write code that could run in environments other than the > one originally in mind. Indeed. > Perhaps it's not a good idea to use `window` > when the code could possibly run in environment that has no idea what > `window` is. Definitely a bad idea. > > so this pattern came to mind: > var global = function(){return this;}(); > However this apparently won't work in ES5 strict which aims to prevent > errors from calling constructors without `new` Right. > > Another hacky idea is to call a function that assumes global when > `this` is unusable. Andrea Giammarchi came up with the shortest form > (http://twitter.com/WebReflection/status/9406207674) > var global = [].sort.call(null); Hack-y is right. > > The question is - is that ES5 strict-safe? Or any other ideas how to > get access to the global without hardcoding its name? I imagine it is not going to foul up ES5 strict mode. > > Of course alternatively the new environment could simply define window > and problem is solved. It isn't up to a random environment to solve issues specific to your script. ;) > E.g. if in some environment the global object > is called `foo`, then just do a global var window = foo; and call it a > day :) No need to do anything like that (and it would certainly cause issues in _browsers_). And what makes you think there will even be a global property (e.g. foo) that references the Global Object? That's what the - this - identifier is for (in the global context). > > Thoughts? Why not just do this in the global context:- var global = this; ....and call it a day. :) That's what I did in My Library, which has no unqualified - window - references. Come to think of it, it has no such _qualified_ references either, which I don't consider ideal. So as not to assume that the Global Object is the window object (despite the fact that it has been observed to be in many browsers), ideally some of those references should have been written:- (global.window || global) The determining factor is whether they are used to qualify references to properties that are known to be specific to the window object in browsers (e.g. the alert method). Of course, this is another case where the declaration of a global - window - variable could cause problems (e.g. if it did not reference the Global Object). Trying to make other environments look like browsers is just as bad an idea as trying to make IE look like a quasi-standard browser (as seen in at least one misguided library). Such environmental differences can be important, depending on context, so should not be arbitrarily spackled over. See also jQuery's height/width methods, which on gets seek to make every element look like it uses the one box model its developers consider to be "correct". They didn't bother to mirror these contortions for set operations, so basically they return dimensions that are of no practical use unless the element's box model happens to be the "correct" one.
From: Thomas 'PointedEars' Lahn on 20 Feb 2010 23:27
Stoyan wrote: > Thanks Thomas! Thank you for keeping proper attribution next time. > [Thomas 'PointedEars' Lahn wrote:] >> [Stoyan wrote:] >> > Or any other ideas how to get access to the global without hardcoding >> > its name? >> What exactly do you mean by "the global"? > > I meant "the global object" Then, as I said, objects do not have names. >> > Of course alternatively the new environment could simply define window >> > and problem is solved. > What hypothetical new environment are you talking about? Why should any >> non-browser environment implement a property that only makes sense in a >> browser environment? > > What I had in mind was - say you're building a library and it's so > useful it makes sense to use the same library in other environments, > not only the browser. For example you can do server-side scripts or > write photoshop scripts. The photoshop environment for example doesn't > have `window`, but it does have a global `app`. > > In such cases when you use a library which uses `window` to refer to > the global object, you can probably do > var window = this; > and the library should work You are still having the misconception that anything other than `this' in the global execution context is supposed to refer to the ECMAScript Global Object. >> > Thoughts? >> >> var _global = this; >> >> in the global execution context. > > I was thinking about when not in the global context? Then you use the global variable or any other property that stores the appropriate value. Preferably you would assign the value to a local variable if you used it repeatedly, to keep the effective scope chain short. > Say your library has a function and inside that function you want check > the global namespace for something. Probably to far-fetched case, I > don't know. Not at all, I am doing this already, for example in my URI-escape wrapper in string.js. > I guess a good approach for a library is to store a global reference > for future internal use, just like you suggested. > > var MyLib = function() { > // my whole lib is here, > // no other global vars leaked What you state in the comment is not entirely true; if MyLib is global, any code can access MyLib._global. However, you could it make so, of course: var MyLib = (function(global) { /* global */ })(this); > return { > someMethod: function() { > var g = MyLib._global; > //... > } > }; > }(); > MyLib._global = this; Or something less ugly. The namespacing approach is heavily overrated (and over-used) to begin with. > This way someMethod() doesn't need to figure out access to the global > object on its own. It does not really matter how you access that object value, only that it is available in the relevant execution contexts. > Thanks again for your reply! > [snip] You are welcome. Thank you in advance for quoting properly next time. <http://jibbering.com/faq/#posting> PointedEars -- Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network. -- Tim Berners-Lee |