Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Puzzling JS Error Date: Sat, 11 Apr 2015 16:15:13 +0200 Organization: PointedEars Software (PES) Lines: 86 Message-ID: <1798717.ojboOnzLPd@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1428761839 553 eJwVysERwDAIA7CVGoJNGSdQs/8IueotbC52OEHHYI4iImnzOpSilVbiy/qPN3KjqKO2XWn+XBobEO8= (11 Apr 2015 14:17:19 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Sat, 11 Apr 2015 14:17:19 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwNyscBwDAIBLCVwHCUcWzK/iMkegtibOVqMMVi65J55C1prlXupkazkpOMh0eMwPKdF3cnV+U8jT8tSg/PB1aaFZg= Cancel-Lock: sha1:qse5cTgAHWR7ReDbXTwcwADHTPM= X-NNTP-Posting-Host: eJwFwYEBwDAEBMCVFE+NI+L3HyF3sPhi0gPhIEhzr9yRo9Tbdyub6Y2j2BU7NhMKUErzd30slxEz Xref: csiph.com comp.lang.javascript:27315 JJ wrote: > On Thu, 9 Apr 2015 11:49:46 -0600, Mel Smith wrote: >> var HTTP; >> /* >> // problem in this next statement >> if (HTTP && (typeof HTTP !== "object" || HTTP.NAME)) { >> throw new Error("Namespace 'HTTP' already exists"); >> } >> */ >> alert("Ready toComplete Ajax set up.") ; >> […] > > The reason why it fails is already explained by others. But you have misunderstood it anyway. Again: Variables that have been declared but not implicitly initialized are initialized with the “undefined” value. !!undefined === false. I do not see how this code could generate a runtime error (not: exception) anyway. If HTTP === undefined or HTTP === null, logical shortcut evaluation prevents what follows the “HTTP” expression from being evaluated, especially HTTP.NAME which would throw a TypeError exception if HTTP === undefined or HTTP === null (because those are primitive values that are not convertible to objects – “undefined/null has no properties”). The only way that I can see this code to generate a runtime error is when “HTTP” refers to an object that type-converts to true, or a host object that cannot be type-converted, “typeof” on it yields "object", and it has a getter for a “NAME” property that throws an exception. > As for the fix, use this. No, do not. > //var HTTP; //don't declare It is *wrong* not to declare “HTTP” a variable here. It causes a ReferenceError in strict mode to assign to such a pseudo-variable (as the OP does) later. > if (typeof HTTP !== "undefined" && HTTP.NAME) { That should work. However, it is pseudo-security. Nothing prevents anyone else from adding a “NAME” property to their object referrable by “HTTP”. Because of that, I would simply write if (typeof HTTP != "undefined") or in my case I have written if (typeof jsx.net == "undefined") { /** * @namespace */ jsx.net = {}; } // […] jsx.net.http = { // […] } It is a good idea to have one’s own namespace¹ (as much as possible) for one’s own objects. “HTTP” is too simple, collisions are likely. Note that I am not throwing exceptions if there is already a “jsx.net.http”; I simply try to overwrite it. Why? Because it could be my own. A possibility to improve efficiency would be to skip initialization if already initialized; but it may be better to fix the problem that caused duplicate loading instead. BTW, The “!==” instead of “!=” adds no efficiency here as both operands are of the same type, String; however, it may quiet code linters such as JSHint. ______ ¹ for lack of a better word -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.