Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #7956 > unrolled thread
| Started by | Dom Bannon <nospam@nospam.com> |
|---|---|
| First post | 2011-11-03 18:07 +0000 |
| Last post | 2011-11-03 20:54 +0100 |
| Articles | 7 — 4 participants |
Back to article view | Back to comp.lang.javascript
Newbie Q's: references, scopes, overwrites Dom Bannon <nospam@nospam.com> - 2011-11-03 18:07 +0000
Re: Newbie Q's: references, scopes, overwrites Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-03 20:11 +0100
Re: Newbie Q's: references, scopes, overwrites Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-03 20:17 +0100
Re: Newbie Q's: references, scopes, overwrites Dom Bannon <nospam@nospam.com> - 2011-11-03 20:07 +0000
Re: Newbie Q's: references, scopes, overwrites Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-03 22:33 +0100
Re: Newbie Q's: references, scopes, overwrites Antony Scriven <adscriven@gmail.com> - 2011-11-03 19:32 -0700
Re: Newbie Q's: references, scopes, overwrites Elegie <elegie@anonymous.invalid> - 2011-11-03 20:54 +0100
| From | Dom Bannon <nospam@nospam.com> |
|---|---|
| Date | 2011-11-03 18:07 +0000 |
| Subject | Newbie Q's: references, scopes, overwrites |
| Message-ID | <fbk5b7dp4brgoenop5rogsol1jv2lveatj@4ax.com> |
Sorry for the newbie question - I write several languages but my
JavaScript is very limited. I have a problem with some code which
displays an svg file received via Ajax. The top-level script includes
these lines:
1 var svg = xhr.responseXML.documentElement;
2 svg = cloneToDoc(svg); // portable importNode
3 window.svgRoot = svg;
4 document.body.appendChild(svg);
5 delete window.svgRoot; // <- problem
The script then terminates. The incoming Ajax message ('svg') is a
script, that references a couple of additional scripts, and I rely on
one of them to be run when it's loaded (presumably on 'appendChild',
but I'm not sure).
This works, but only if line 5 is commented out. If it's left in, I
get various issues which have the feel of a memory over-write. I don't
really know what to do here, because I don't understand the window
object, or the scoping issues, or much else. The guy who wrote it says
that line 5 is "just cleanup, removing the global svgRoot property
from the window after appending the file".
Dumb question #1: what exactly is 'window'? Is it an object which
represents the currently visible window? Presumably it's still in
scope, and global, and represents the same window when the other (svg)
scripts are running?
#2: what is line 3 doing? Is it auto-declaring a new 'svgRoot' var in
'window'? Can you just do that? Is the author just finding a
convenient location to put a global?
#3: the rest of the code manipulates the svg via window.svgRoot,
rather than getting a reference to the new child in the document body.
Is this Ok? Is line 4 appending a reference to svg, or copying svg, or
somehting else? Presumably line 5 doesn't actually delete the new
child?
#5: is there a memory overwite/leak detect tool for JavaScript?
Thanks if you managed to read this far... :)
[toc] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-11-03 20:11 +0100 |
| Message-ID | <3004336.SPkdTlGXAF@PointedEars.de> |
| In reply to | #7956 |
Dom Bannon wrote:
> Sorry for the newbie question - I write several languages but my
> JavaScript is very limited. I have a problem with some code which
> displays an svg file received via Ajax. The top-level script includes
> these lines:
>
> 1 var svg = xhr.responseXML.documentElement;
> 2 svg = cloneToDoc(svg); // portable importNode
> 3 window.svgRoot = svg;
> 4 document.body.appendChild(svg);
> 5 delete window.svgRoot; // <- problem
>
> The script then terminates.
That is to be expected. But does it terminate with an error? If yes, what
does the error message say?
> The incoming Ajax message ('svg') is a script, that references a couple of
> additional scripts, and I rely on one of them to be run when it's loaded
> (presumably on 'appendChild', but I'm not sure).
This is not going to happen.
> This works,
It is generally unreliable. The only way to be rather sure that new script
code will be executed is to append a new `script' element.
This might be an exception if the parent document is declared XHTML 1.1 +
SVG + MathML, or HTML5, and you are actually appending an `svg' element
node, where the script that it contains pertains to and is triggered by SVG
elements only. But your description indicates otherwise.
> but only if line 5 is commented out.
Line 5 attempts to delete a property of a host object, which may not be
possible.
> If it's left in, I get various issues which have the feel of a memory
> over-write.
What issues? How did you get that impression?
> I don't really know what to do here, because I don't understand the window
> object, or the scoping issues, or much else.
This does not appear to have anything to do with scope.
> The guy who wrote it says that line 5 is "just cleanup, removing the
> global svgRoot property from the window after appending the file".
That description is correct in general, but they are otherwise clueless.
See below.
> Dumb question #1: what exactly is 'window'?
It is a host-defined property of the ECMAScript Global Object which value is
a reference to an object that represents the view of the document that
contains the script code.
> Is it an object which represents the currently visible window?
In a sense, yes.
> Presumably it's still in scope, and global, and represents the same window
> when the other (svg) scripts are running?
This is not a valid question. Please restate your request.
> #2: what is line 3 doing?
It is an attempt to create or overwrite the property of the object referred
to by `window', that is named `svgRoot', with the value of the `svg'
variable.
> Is it auto-declaring a new 'svgRoot' var in 'window'?
No.
> Can you just do that?
No.
> Is the author just finding a convenient location to put a global?
Yes, and he might have been misguided by Douglas Crockford's notion that
this was the (proper) way to do that.
> #3: the rest of the code manipulates the svg via window.svgRoot,
> rather than getting a reference to the new child in the document body.
> Is this Ok?
That depends on whether the object referred to by `window' already had a
`svgRoot' property in the first place, whether it has one after the
assignment in line 3, and whether the value of that property is the value of
`svg'.
The property creation may fail because the object referred to by `window' is
a host object (not a native one), and the property value modification may
fail because an existing property of that name was defined to be read-only.
> Is line 4 appending a reference to svg, or copying svg, or
> somehting else?
Yes.
> Presumably line 5 doesn't actually delete the new child?
Please restate your request.
> #5: is there a memory overwite/leak detect tool for JavaScript?
Yes.
PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300dec7@news.demon.co.uk> (2004)
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-11-03 20:17 +0100 |
| Message-ID | <1547431.qVoOGUtdWV@PointedEars.de> |
| In reply to | #7958 |
Thomas 'PointedEars' Lahn wrote: > Dom Bannon wrote: >> Dumb question #1: what exactly is 'window'? > > It is a host-defined property of the ECMAScript Global Object which value > is a reference to an object that represents the view of the document that > contains the script code. … or includes it with a `script' element that has a `src' attribute specified. 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
[toc] | [prev] | [next] | [standalone]
| From | Dom Bannon <nospam@nospam.com> |
|---|---|
| Date | 2011-11-03 20:07 +0000 |
| Message-ID | <cvq5b79tt95v4vk2dh4vpiua5a238jo0n4@4ax.com> |
| In reply to | #7958 |
On Thu, 03 Nov 2011 20:11:15 +0100, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
>Dom Bannon wrote:
>> The script then terminates.
>
>That is to be expected. But does it terminate with an error? If yes, what
>does the error message say?
No, sorry, I meant that that was the end of the script. It's just a
short script that does a one-off Ajax request to load in the other
scripts:
<script type="text/ecmascript"><![CDATA[
setTimeout(function(){
var xhr = new XMLHttpRequest;
xhr.open('get','test2.svg',true);
xhr.onreadystatechange = function(){
if (xhr.readyState != 4) return;
var svg = xhr.responseXML.documentElement;
svg = cloneToDoc(svg); // portable importNode
window.svgRoot = svg;
document.body.appendChild(svg);
delete window.svgRoot; // <- problem
};
xhr.send();
},1000);
function cloneToDoc(node,doc){
...
}
]]></script>
>> This works,
>
>It is generally unreliable. The only way to be rather sure that new script
>code will be executed is to append a new `script' element.
Is the 'document.body.appendChild(svg)' sufficient? This is an xhtml
doc, content type 'application/xhtml+xml'. The script that is loaded
(ie. node 'svg') includes this code, which initialises everything and
produces the image:
if(!window.svgRoot) {
svgRoot = document.documentElement;
}
try {
...init code in one of the other svg scripts
} catch(e) {
...error report
}
Note the test for '!window.svgRoot', despite the fact that the author
previously did a 'delete window.svgRoot' above.
>> but only if line 5 is commented out.
>
>Line 5 attempts to delete a property of a host object, which may not be
>possible.
>
>> If it's left in, I get various issues which have the feel of a memory
>> over-write.
>
>What issues? How did you get that impression?
The immediate error is that both F/F and Opera report that
'group.getBBox()' is not a function call, where 'group' is meant to be
a group node. Note that the svg code itself does actually work when
viewed stand-alone (and this 'getBBox' does work correctly). Tracing
back a bit I find that there is at least one error in
'svgRoot.namespaceURI'; it's set to 'w3.org/1999/xhtml', instead of
'w3.org/2000/svg'.
>> I don't really know what to do here, because I don't understand the window
>> object, or the scoping issues, or much else.
>
>This does not appear to have anything to do with scope.
>
>> The guy who wrote it says that line 5 is "just cleanup, removing the
>> global svgRoot property from the window after appending the file".
>
>That description is correct in general, but they are otherwise clueless.
>See below.
>
>> Presumably it's still in scope, and global, and represents the same window
>> when the other (svg) scripts are running?
>
>This is not a valid question. Please restate your request.
I wanted to find out if it was valid to reference 'window.svgRoot'
from one of the svg scripts but, from what you say elsewhere, it looks
like it is valid.
>> #3: the rest of the code manipulates the svg via window.svgRoot,
>> rather than getting a reference to the new child in the document body.
>> Is this Ok?
>
>That depends on whether the object referred to by `window' already had a
>`svgRoot' property in the first place, whether it has one after the
>assignment in line 3, and whether the value of that property is the value of
>`svg'.
I've just traced through the changes to 'window' with Firebug.
'svgRoot' doesn't exist before the assignment to 'window.svgRoot', and
it does exist after the assignment, and it appears to be correct on a
cursory inspection. So, the author does appear to be simply
auto-declaring a var in 'window'.
>> Presumably line 5 doesn't actually delete the new child?
>
>Please restate your request.
My concern was that 'window.svgRoot' was actually a reference to the
new child created by 'document.body.appendChild(svg)' (line #4), so
deleting the former would actually delete the new child tree. However,
after reading up a bit more, it seems that line #4 actually *moves*
the svg tree from 'window' to the doc body. So line #5 is presumably a
bug anyway, unless it's intended to delete a var which no longer
references anything.
>> #5: is there a memory overwite/leak detect tool for JavaScript?
>
>Yes.
?
Thanks -
Dom
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-11-03 22:33 +0100 |
| Message-ID | <4776975.ypaU67uLZW@PointedEars.de> |
| In reply to | #7963 |
Dom Bannon wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Dom Bannon wrote:
>
> […] It's just a short script that does a one-off Ajax request to load in
> the other scripts:
>
> <script type="text/ecmascript"><![CDATA[
The proper `src' attribute value here is "text/javascript" or
"application/javascript", with the former one being supported best.
> setTimeout(function(){
This should be
window.setTimeout(function() {
> var xhr = new XMLHttpRequest;
IMO constructor calls should include the empty argument list, `()'. If
other environments are targeted as well, alternative code might be needed.
> xhr.open('get','test2.svg',true);
The HTTP verb is GET, so should be the first argument of xhr.open() here.
> xhr.onreadystatechange = function(){
> if (xhr.readyState != 4) return;
And interesting optimization that for some reason did not occur to me until
now (I had favored the branching code over that gauntlet). However, what is
missing here is checking the value of the `status' property, i. e. whether
the request was successful (200), before attempting to process the response
message.
> var svg = xhr.responseXML.documentElement;
> svg = cloneToDoc(svg); // portable importNode
> window.svgRoot = svg;
^^^^^^^^^^^^^^^^
AISB, do not do that …
> document.body.appendChild(svg);
> delete window.svgRoot; // <- problem
^^^^^^^^^^^^^^^^^^^^^
… then you do not have to do that either.
> };
> xhr.send();
The argument list should be `(null)'.
> },1000);
> function cloneToDoc(node,doc){
> ...
> }
You omitted relevant code.
> ]]></script>
>
>>> This works,
>>
>> It is generally unreliable. The only way to be rather sure that new
>> script code will be executed is to append a new `script' element.
>
> Is the 'document.body.appendChild(svg)' sufficient?
That depends on the return value of cloneToDoc(), but generally yes (with
the provision made in my previous article).
> This is an xhtml doc, content type 'application/xhtml+xml'.
The including document? The included document? Both?
> The script that is loaded (ie. node 'svg') includes this code,
A markup document that has an `svg' element as its root element is not a
script; it is either an SVG (Scalable Vector Graphics) document or an
untyped XML document.
> which initialises everything and produces the image:
>
> if(!window.svgRoot) {
> svgRoot = document.documentElement;
> }
> try {
> ...init code in one of the other svg scripts
> } catch(e) {
> ...error report
> }
>
> Note the test for '!window.svgRoot', despite the fact that the author
> previously did a 'delete window.svgRoot' above.
This code does not make sense. However, you omitted relevant parts. It
would be best if you created and provided a minimal test case at a publicly
accessible location.
>>> but only if line 5 is commented out.
>> […]
>>> If it's left in, I get various issues which have the feel of a memory
>>> over-write.
>>
>> What issues? How did you get that impression?
>
> The immediate error is that both F/F and Opera report that
> 'group.getBBox()' is not a function call, where 'group' is meant to be
> a group node.
As we have not seen what `group' refers to yet, that is useless, if
generally pertinent, information at this time.
You have not explained your impression of a "memory over-write".
> Note that the svg code itself does actually work when
> viewed stand-alone (and this 'getBBox' does work correctly). Tracing
> back a bit I find that there is at least one error in
> 'svgRoot.namespaceURI'; it's set to 'w3.org/1999/xhtml', instead of
> 'w3.org/2000/svg'.
This code looks more and more bogus.
>>> Presumably it's still in scope, and global, and represents the same
>>> window when the other (svg) scripts are running?
>> This is not a valid question. Please restate your request.
>
> I wanted to find out if it was valid to reference 'window.svgRoot'
> from one of the svg scripts but, from what you say elsewhere, it looks
> like it is valid.
It is syntactically valid, but (AISB) rather unwise.
>>> #3: the rest of the code manipulates the svg via window.svgRoot,
>>> rather than getting a reference to the new child in the document body.
>>> Is this Ok?
>>
>> That depends on whether the object referred to by `window' already had a
>> `svgRoot' property in the first place, whether it has one after the
>> assignment in line 3, and whether the value of that property is the value
>> of `svg'.
>
> I've just traced through the changes to 'window' with Firebug.
So your target runtime environment is Mozilla Firefox? Which version(s)?
> 'svgRoot' doesn't exist before the assignment to 'window.svgRoot', and
> it does exist after the assignment, and it appears to be correct on a
> cursory inspection. So, the author does appear to be simply
> auto-declaring a var in 'window'.
Yes, that only appears to be so. I have already explained what really
happens.
>>> Presumably line 5 doesn't actually delete the new child?
>> Please restate your request.
>
> My concern was that 'window.svgRoot' was actually a reference to the
> new child created by 'document.body.appendChild(svg)' (line #4), so
> deleting the former would actually delete the new child tree.
Deleting a property of an object usually does not remove a node from a
document tree. However, as host objects are involved, all bets are off.
> However, after reading up a bit more, it seems that line #4 actually
> *moves* the svg tree from 'window' to the doc body.
That would depend on what cloneToDoc() does. If it does what its name says
(to clone), then nothing is moved. Certainly nothing is moved "from
'window' to the doc body".
> So line #5 is presumably a bug anyway, unless it's intended to delete a
> var which no longer references anything.
The whole approach looks like one big bug to me at this point.
>>> #5: is there a memory overwite/leak detect tool for JavaScript?
>> Yes.
>
> ?
<http://catb.org/~esr/faqs/smart-questions.html>
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>
[toc] | [prev] | [next] | [standalone]
| From | Antony Scriven <adscriven@gmail.com> |
|---|---|
| Date | 2011-11-03 19:32 -0700 |
| Message-ID | <d16db8b4-d3d4-4479-b628-18a0b9c54cdb@f29g2000yqa.googlegroups.com> |
| In reply to | #7966 |
On Nov 3, 9:33 pm, Thomas 'PointedEars' Lahn wrote: > Dom Bannon wrote: > > Thomas 'PointedEars' Lahn wrote: > > > Dom Bannon wrote: > > [...] > > > > > #5: is there a memory overwite/leak detect tool for > > > > JavaScript? > > > Yes. > > > ? > > <http://catb.org/~esr/faqs/smart-questions.html> Thomas, that's standard English idiom. A plain yes or no answer is not what Dom asked for. It's not expected to be interpreted literally, hence the '?'. The strong implication is that you should provide details if you have them. This sort of indirection is routinely used to express politeness in English. --Antony
[toc] | [prev] | [next] | [standalone]
| From | Elegie <elegie@anonymous.invalid> |
|---|---|
| Date | 2011-11-03 20:54 +0100 |
| Message-ID | <4eb2f16f$0$622$426a74cc@news.free.fr> |
| In reply to | #7956 |
On 03/11/2011 19:07, Dom Bannon wrote : Hello, <snip> > 1 var svg = xhr.responseXML.documentElement; > 2 svg = cloneToDoc(svg); // portable importNode > 3 window.svgRoot = svg; > 4 document.body.appendChild(svg); > 5 delete window.svgRoot; //<- problem <snip> > This works, but only if line 5 is commented out. If it's left in, I > get various issues which have the feel of a memory over-write. I don't > really know what to do here, because I don't understand the window > object, or the scoping issues, or much else. The guy who wrote it says > that line 5 is "just cleanup, removing the global svgRoot property > from the window after appending the file". I am not familiar with SVG, but will try and give you some pointers regarding your questions below. > Dumb question #1: what exactly is 'window'? Is it an object which > represents the currently visible window? Presumably it's still in > scope, and global, and represents the same window when the other (svg) > scripts are running? Basically, yes. But let us consider all this from the browser perspective. A browser will emit and receive HTTP commands. This means that: - it must provide a way for the user to build and send HTTP commands. This can be done using a view and capturing user events on this view (like submitting a form or clicking a link), or by providing actions on the UI itself (like navigating an address bar or activating a favorite), - it must process the received commands. Received commands can range from "display a view which you will build using this HTML", to "here's an image, use it as a reference when building the current view", or "here comes a .stuff file, do something about it". What's important here is that the browser maintains a view with which the user can interact. It also probably maintains its own controller and model, leveraging the MVC pattern. Browser views are built using a component-based model. The top element of the model is the "window" element, and hierarchically attached to this window are other elements (like text, images, form controls). HTML, in a certain way, is the serialized form of the view. The browser, while rendering the view, will also load engines, which will be able to manipulate the view in certain ways. For instance, a CSS engine will be able to apply a certain rendering onto view elements, and a script engine (using languages like javascript, VBScript, PerlScript...) will be able to directly manipulate the structure. Received HTTP commands may contain CSS or script instructions (declared directly into the HTML), or may reference external resources to be applied on the view (CSS/script includes). What is nice is that the browser allows an author to manipulate the view in many ways, providing a set of more-or-less standardized API. > #2: what is line 3 doing? Is it auto-declaring a new 'svgRoot' var in > 'window'? Can you just do that? Is the author just finding a > convenient location to put a global? This is a tricky question, and the quick answer could be either "yes, but" or "no, but" :) What's important to notice, here, is that the "window" object is really a view element, while the "var" keyword is used to define a javascript variable in a lexical scope. Both should have nothing in common; but somehow, most browsers try and join the "window" element with the global javascript object, making a global declaration using the "var" keyword roughly (but not completely) equivalent to the property-setting on the window object. For a web author, the difference should not matter (though it should be preferable to use the "var" keyword, as creating "expando properties" - i.e. properties on host objects in general - may not always be safe). > #3: the rest of the code manipulates the svg via window.svgRoot, > rather than getting a reference to the new child in the document body. > Is this Ok? Yes, of course, because both are referencing the same object (the SVG fragment). > Is line 4 appending a reference to svg, or copying svg, or > somehting else? The SVG variable certains contains a document fragment. The "document" element refers to a child of the "window" element, and its appendChild method programmatically adds some nodes to its children. To put it in a nutshell, it is used to dynamically add elements to the view. > Presumably line 5 doesn't actually delete the new > child? The "delete" method is used to remove a property from an object. If that property contains a reference to some object, then this reference is freed and the object can be garbage-collected (unless other references to this object remain). Doing "obj.prop = null;" would suffice, though. > #5: is there a memory overwite/leak detect tool for JavaScript? I don't know, sorry. But I know that some memory leaks happen in some browsers, when a circular reference is formed between a view object and a script object (both objects stay in the memory and are never cleaned up). A common practice is to free the problematic references, so as to break the circular reference. Maybe this is the issue that you have been facing with your script. Regards, Elegie.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web