From: Stoyan on
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
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
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
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
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