window. or this. prefix

View: New views
8 Messages — Rating Filter:   Alert me  

window. or this. prefix

by mikewse :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Joe,
 
I saw that you've gone from
    var dwr = {};
to
    window['dwr'] = {};
and then to
    this.dwr = {};
in engine/util.js. (BTW: in what version should the old DWREngine/DWRUtil names disappear?)
 
I'm following you with the window version, but what is the rationale for the latest version with |this| ?
Maybe it is because of integrating with unit tests, or for multiple frame windows? Either way it would be interesting to have a discussion about what we want to do in these cases.
 
Best regards
Mike

Re: window. or this. prefix

by Joe Walker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I've wanted to find a better version of 'var dwr = {};' for a while, mostly because every JS checker complains. I'm not sure why.  It's worse that when used with an 'if' we might like to use a block, but { var dwr = {}; } feels like it shouldn't affect the surroundings. (though I appreciate that it does).

So doing window['dwr'] felt like a decent fix, however, and this is the strange bit, on IE:

window['dwr'] = { };
dwr.wibble = 'x';
if (dwr == null) var dwr = {};

Ends up re-defining dwr because (dwr == null) is true. I have no idea why, but IE was broken because not all declarations of DWR did it in the same way. In the end I copied what Dojo does.

Joe.


On 11/2/07, Mike Wilson <mikewse@...> wrote:
Hi Joe,
 
I saw that you've gone from
    var dwr = {};
to
    window['dwr'] = {};
and then to
    this.dwr = {};
in engine/util.js. (BTW: in what version should the old DWREngine/DWRUtil names disappear?)
 
I'm following you with the window version, but what is the rationale for the latest version with |this| ?
Maybe it is because of integrating with unit tests, or for multiple frame windows? Either way it would be interesting to have a discussion about what we want to do in these cases.
 
Best regards
Mike


RE: window. or this. prefix

by mikewse :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've wanted to find a better version of 'var dwr = {};' for a while, mostly because every JS checker complains. I'm not sure why. 
I think they expect a statement and not a declaration in the one-liner. Same problem we had with Safari and "if ( expr ) function()...".
As we want "dwr" in the global scope it would do fine without a |var| declaration though.
It's worse that when used with an 'if' we might like to use a block, but { var dwr = {}; } feels like it shouldn't affect the surroundings. (though I appreciate that it does).  
Well, |var|-declared variables in JavaScript register themselves in the nearest scope and new scopes are created for functions, not for individual {} blocks.
So doing window['dwr'] felt like a decent fix, however, and this is the strange bit, on IE:

window['dwr'] = { };
dwr.wibble = 'x';
if (dwr == null) var dwr = {}; 
 
Ends up re-defining dwr because (dwr == null) is true. I have no idea why, but IE was broken because not all declarations of DWR did it in the same way.  
I've tried but can't trigger this bug. Anything else I need to do?
In the end I copied what Dojo does.  
Ok, they have a lot of handling for other environments than the browser. In the browser this===window. For that reason I think the current |this| code would work just the same with |window|.
 
If the aim is to always register our variables on the global object I think it is clearer to use |window|.
 
Best regards
Mike

Re: window. or this. prefix

by Joe Walker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


If you sync to a DWR from a week ago you should see engine.js use window['dwr'] and interface scripts use var dwr (IIRC), and IE detects dwr == null and then goes on to re-declare it.

Joe.

On 11/2/07, Mike Wilson <mikewse@...> wrote:
I've wanted to find a better version of 'var dwr = {};' for a while, mostly because every JS checker complains. I'm not sure why. 
I think they expect a statement and not a declaration in the one-liner. Same problem we had with Safari and "if ( expr ) function()...".
As we want "dwr" in the global scope it would do fine without a |var| declaration though.
It's worse that when used with an 'if' we might like to use a block, but { var dwr = {}; } feels like it shouldn't affect the surroundings. (though I appreciate that it does).  
Well, |var|-declared variables in JavaScript register themselves in the nearest scope and new scopes are created for functions, not for individual {} blocks.
So doing window['dwr'] felt like a decent fix, however, and this is the strange bit, on IE:

window['dwr'] = { };
dwr.wibble = 'x';
if (dwr == null) var dwr = {}; 
 
Ends up re-defining dwr because (dwr == null) is true. I have no idea why, but IE was broken because not all declarations of DWR did it in the same way.  
I've tried but can't trigger this bug. Anything else I need to do?
In the end I copied what Dojo does.  
Ok, they have a lot of handling for other environments than the browser. In the browser this===window. For that reason I think the current |this| code would work just the same with |window|.
 
If the aim is to always register our variables on the global object I think it is clearer to use |window|.
 
Best regards
Mike


RE: window. or this. prefix

by mikewse :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've been planning to check up on this and finally came around doing it ;-)

So doing window['dwr'] felt like a decent fix, however, and this is the strange bit, on IE:

window['dwr'] = { };
dwr.wibble = 'x';
if (dwr == null) var dwr = {};  
 
Ends up re-defining dwr because (dwr == null) is true. I have no idea why, but IE was broken because not all declarations of DWR did it in the same way.  
I've tried but can't trigger this bug. Anything else I need to do? 
 
If you sync to a DWR from a week ago you should see engine.js use window['dwr'] and interface scripts use var dwr (IIRC), and IE detects dwr == null and then goes on to re-declare it.
I found the source of this problem and it is because of an IE bug I haven't seen before, combined with the current (of October 22) anatomy of DWR script files.
A page using DWR normally includes engine.js and one or more interface scripts, and all these files redefine dwr[.engine] whenever needed:
<script type='text/javascript' src='dwr/engine.js'>
      if (window['dwr'] == null) window['dwr'] = {};
      if (dwr['engine'] == null) dwr['engine'] = {}; 
 
<script type='text/javascript' src='dwr/interface/serviceObj.js'>
    if (dwr == null) var dwr = {};
    if (dwr.engine == null) dwr.engine = {};
Note that the |dwr| object is handled as a window property in engine.js but as a global variable (var) in the interface script. This is what triggers the IE bug, and what happens is that when execution enters the second script element, IE does this:
  1. Registers all global variables declared in this section (this is, and should, be done without considering true/false conditions in if-branches).
  2. Somehow IE misses that |dwr| has already been defined and does what it usually does when declaring a new, previously non-existing, variable: sets its value to undefined.
  3. After declaring variables (and compiling code) it is time to execute global code. The "if (dwr == null)" will now be true and the assignment "dwr = {}" will be executed.
So the bug is triggered in step (2) when |dwr| has been defined through a window property. It doesn't happen when a var-declaration is used in the first script element, or when both script elements use the window property.
It is quite easy to reproduce the problem. Just insert the following two script elements in a page:
<script type='text/javascript'>
      window.myObj = {};
      alert( myObj ); // It's defined here...
</script>
<script type='text/javascript'>
      alert( myObj ); // ... but not here
      if (myObj == null) var myObj = {};
      alert( myObj ); // ...  and here our code has reassigned it 
</script>
The new dojo inspired code using |this| doesn't trigger the bug as it doesn't use a var-declaration in the interface script:
<script type='text/javascript' src='dwr/engine.js'>
    if (typeof this['dwr'] == 'undefined') { dwr = { }; }
  
<script type='text/javascript' src='dwr/interface/serviceObj.js'> 
    if (typeof this['dwr'] == 'undefined') this.dwr = {};
So, an easy way of avoiding the IE bug is to declare the |dwr| object in the same way in all places (which is almost true now).
 
There is one additional factor that could be interesting: going back to using a var-declaration (everywhere) would avoid the hard-to-find IE bug when an HTML element is given an id of "dwr" and IE declares a corresponding JS variable. This will not very often be a problem though, as engine.js is normally included before any markup with ids so our |dwr| variable "will win".
 
But my vote is still on using |window| instead of |this| for clarity in this code ;-)
 
Best regards
Mike

Re: window. or this. prefix

by Joe Walker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


There's been some talk about using DWR in Jaxer as a way to remote from a Jaxer server into Java, now in this case there is a window object even though we are on the server, so this isn't a cast iron argument for using this in place of window, however, I think it indicates that there may be cases where engine.js isn't always used in a browser as we know it.

YSlow (the firebug plugin) recommends adding scripts at the bottom of the page, so maybe the clash of dwr's is more likely that we thought?

Joe.

On Feb 18, 2008 8:08 PM, Mike Wilson <mikewse@...> wrote:
I've been planning to check up on this and finally came around doing it ;-)

So doing window['dwr'] felt like a decent fix, however, and this is the strange bit, on IE:

window['dwr'] = { };
dwr.wibble = 'x';
if (dwr == null) var dwr = {};  
 
Ends up re-defining dwr because (dwr == null) is true. I have no idea why, but IE was broken because not all declarations of DWR did it in the same way.  
I've tried but can't trigger this bug. Anything else I need to do? 
 
If you sync to a DWR from a week ago you should see engine.js use window['dwr'] and interface scripts use var dwr (IIRC), and IE detects dwr == null and then goes on to re-declare it.
I found the source of this problem and it is because of an IE bug I haven't seen before, combined with the current (of October 22) anatomy of DWR script files.
A page using DWR normally includes engine.js and one or more interface scripts, and all these files redefine dwr[.engine] whenever needed:
<script type='text/javascript' src='dwr/engine.js'>
      if (window['dwr'] == null) window['dwr'] = {};
      if (dwr['engine'] == null) dwr['engine'] = {}; 
 
<script type='text/javascript' src='dwr/interface/serviceObj.js'>
    if (dwr == null) var dwr = {};
    if (dwr.engine == null) dwr.engine = {};
Note that the |dwr| object is handled as a window property in engine.js but as a global variable (var) in the interface script. This is what triggers the IE bug, and what happens is that when execution enters the second script element, IE does this:
  1. Registers all global variables declared in this section (this is, and should, be done without considering true/false conditions in if-branches).
  2. Somehow IE misses that |dwr| has already been defined and does what it usually does when declaring a new, previously non-existing, variable: sets its value to undefined.
  3. After declaring variables (and compiling code) it is time to execute global code. The "if (dwr == null)" will now be true and the assignment "dwr = {}" will be executed.
So the bug is triggered in step (2) when |dwr| has been defined through a window property. It doesn't happen when a var-declaration is used in the first script element, or when both script elements use the window property.
It is quite easy to reproduce the problem. Just insert the following two script elements in a page:
<script type='text/javascript'>
      window.myObj = {};
      alert( myObj ); // It's defined here...
</script>
<script type='text/javascript'>
      alert( myObj ); // ... but not here
      if (myObj == null) var myObj = {};
      alert( myObj ); // ...  and here our code has reassigned it 
</script>
The new dojo inspired code using |this| doesn't trigger the bug as it doesn't use a var-declaration in the interface script:
<script type='text/javascript' src='dwr/engine.js'>
    if (typeof this['dwr'] == 'undefined') { dwr = { }; }
  
<script type='text/javascript' src='dwr/interface/serviceObj.js'> 
    if (typeof this['dwr'] == 'undefined') this.dwr = {};
So, an easy way of avoiding the IE bug is to declare the |dwr| object in the same way in all places (which is almost true now).
 
There is one additional factor that could be interesting: going back to using a var-declaration (everywhere) would avoid the hard-to-find IE bug when an HTML element is given an id of "dwr" and IE declares a corresponding JS variable. This will not very often be a problem though, as engine.js is normally included before any markup with ids so our |dwr| variable "will win".
 
But my vote is still on using |window| instead of |this| for clarity in this code ;-)
 
Best regards
Mike


RE: window. or this. prefix

by mikewse :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well, if people start putting their scripts at the bottom of the page it may be better to go back to the var syntax. That would take away |this| or |window| completely so I guess then we don't have to choose between them :-).
 
What's the reason for using a |this.| or |window.| prefix anyway? (more than clarity)
 
I guess a possible risk would be scenarious where bugs or misuse makes our |var| register in the wrong context, something along the lines of IE eval's global context limitations, if DWR would f ex be included through a package system that doesn't know about IE's execScript.
For reference, Prototype uses the |var| syntax and Dojo uses |this.|.
 
Best regards
Mike


From: joseph.walker@... [mailto:joseph.walker@...] On Behalf Of Joe Walker
Sent: den 19 februari 2008 15:00
To: dev@...
Subject: Re: [dwr-dev] window. or this. prefix


There's been some talk about using DWR in Jaxer as a way to remote from a Jaxer server into Java, now in this case there is a window object even though we are on the server, so this isn't a cast iron argument for using this in place of window, however, I think it indicates that there may be cases where engine.js isn't always used in a browser as we know it.

YSlow (the firebug plugin) recommends adding scripts at the bottom of the page, so maybe the clash of dwr's is more likely that we thought?

Joe.

On Feb 18, 2008 8:08 PM, Mike Wilson <mikewse@...> wrote:
I've been planning to check up on this and finally came around doing it ;-)

So doing window['dwr'] felt like a decent fix, however, and this is the strange bit, on IE:

window['dwr'] = { };
dwr.wibble = 'x';
if (dwr == null) var dwr = {};  

Ends up re-defining dwr because (dwr == null) is true. I have no idea why, but IE was broken because not all declarations of DWR did it in the same way.  
I've tried but can't trigger this bug. Anything else I need to do? 
 
If you sync to a DWR from a week ago you should see engine.js use window['dwr'] and interface scripts use var dwr (IIRC), and IE detects dwr == null and then goes on to re-declare it.
I found the source of this problem and it is because of an IE bug I haven't seen before, combined with the current (of October 22) anatomy of DWR script files.
A page using DWR normally includes engine.js and one or more interface scripts, and all these files redefine dwr[.engine] whenever needed:
<script type='text/javascript' src='dwr/engine.js'>
      if (window['dwr'] == null) window['dwr'] = {};
      if (dwr['engine'] == null) dwr['engine'] = {}; 
 
<script type='text/javascript' src='dwr/interface/serviceObj.js'>
    if (dwr == null) var dwr = {};
    if (dwr.engine == null) dwr.engine = {};
Note that the |dwr| object is handled as a window property in engine.js but as a global variable (var) in the interface script. This is what triggers the IE bug, and what happens is that when execution enters the second script element, IE does this:
  1. Registers all global variables declared in this section (this is, and should, be done without considering true/false conditions in if-branches).
  2. Somehow IE misses that |dwr| has already been defined and does what it usually does when declaring a new, previously non-existing, variable: sets its value to undefined.
  3. After declaring variables (and compiling code) it is time to execute global code. The "if (dwr == null)" will now be true and the assignment "dwr = {}" will be executed.
So the bug is triggered in step (2) when |dwr| has been defined through a window property. It doesn't happen when a var-declaration is used in the first script element, or when both script elements use the window property.
It is quite easy to reproduce the problem. Just insert the following two script elements in a page:
<script type='text/javascript'>
      window.myObj = {};
      alert( myObj ); // It's defined here...
</script>
<script type='text/javascript'>
      alert( myObj ); // ... but not here
      if (myObj == null) var myObj = {};
      alert( myObj ); // ...  and here our code has reassigned it 
</script>
The new dojo inspired code using |this| doesn't trigger the bug as it doesn't use a var-declaration in the interface script:
<script type='text/javascript' src='dwr/engine.js'>
    if (typeof this['dwr'] == 'undefined') { dwr = { }; }
  
<script type='text/javascript' src='dwr/interface/serviceObj.js'> 
    if (typeof this['dwr'] == 'undefined') this.dwr = {};
So, an easy way of avoiding the IE bug is to declare the |dwr| object in the same way in all places (which is almost true now).
 
There is one additional factor that could be interesting: going back to using a var-declaration (everywhere) would avoid the hard-to-find IE bug when an HTML element is given an id of "dwr" and IE declares a corresponding JS variable. This will not very often be a problem though, as engine.js is normally included before any markup with ids so our |dwr| variable "will win".
 
But my vote is still on using |window| instead of |this| for clarity in this code ;-)
 
Best regards
Mike


Re: window. or this. prefix

by Joe Walker-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Feb 20, 2008 11:52 AM, Mike Wilson <mikewse@...> wrote:
Well, if people start putting their scripts at the bottom of the page it may be better to go back to the var syntax. That would take away |this| or |window| completely so I guess then we don't have to choose between them :-).
 
What's the reason for using a |this.| or |window.| prefix anyway? (more than clarity

I was banging my head against the var problem, and thinking that sometimes this != window, so I copied Dojo and everything worked, however this was  down to me doing the same thing everywhere.
However if a system similar to Jaxer uses DWR for remoting then there may be no window object. So there is something to be gained by using |this|, however I agree with the point about clarity.

I think the only reason I'm not jumping to go back to var, is not liking it's use in a global context, and not liking it's interaction with IE. But the script-at-the-bottom argument does tend to overrule that a bit. Hmmm

I guess a possible risk would be scenarious where bugs or misuse makes our |var| register in the wrong context, something along the lines of IE eval's global context limitations, if DWR would f ex be included through a package system that doesn't know about IE's execScript.
For reference, Prototype uses the |var| syntax and Dojo uses |this.|.

Joe