0

While browsing, I frequently take a look at the source code of webpage to check how certain things have been realized.

One thing I frequently see is stuff like: window.myApp.apiKey = 12345; or window.myApp.welcomeMsg = "Hello there!";

I always was under the impression that it's bad practice to attach properties to the window object (like explained in this accepted answer), but it looks like myApp is used as a kind of namespace & since it's often the brand name, it's unlikely to clash with anything.

Still – how is it okay to do it this way, are there any indicators for that? (i.e. when I know no 3rd libraries will be used in the project, which can change quickly in real life).

Community
  • 1
  • 1
Sven
  • 12,997
  • 27
  • 90
  • 148
  • It is not ok anymore, nowadays we have modules. – elclanrs Jan 22 '15 at 18:44
  • @elclanrs Could you please elaborate on this a bit more? – Sven Jan 22 '15 at 18:48
  • You cannot escape attaching properties to the window. This is the master object. However you should reduce this to a minimum or use non-generic names for your expressions. – Mouser Jan 22 '15 at 19:02
  • What I mean is you can use modules in the browser and do `var api = require('api')`. Check out [Browserify](http://browserify.org/) for example. – elclanrs Jan 22 '15 at 19:04
  • @elclanrs: Yep, but if you're doing that, you're still attaching at least one property to root scope regardless. Do `var api = require('api'); console.log(window.api);` ... property on the window object. There is NO escaping _at least one_ – BLSully Jan 22 '15 at 19:09
  • 1
    @BLSully `(function () { var api = …; })()` – Ingo Bürk Jan 22 '15 at 19:13
  • Browserify will add the IIFE for you anyway. – elclanrs Jan 22 '15 at 19:16
  • 1
    @IngoBürk: `window.require` ... there's ALWAYS at least one developer-added property... whether or not it's your code, a framework, or some smaller library – BLSully Jan 22 '15 at 19:22
  • 1
    @BLSully Once you start gluing components together, yes, you won't be able to escape any kind of global. Which isn't even bad. Every language has that problem. They make it harder by adding namespaces, but ultimately it's the same. A `java.lang.String` is conceptually no different from `window['java']['lang']['String']`. – Ingo Bürk Jan 22 '15 at 19:26
  • 1
    That's all I was trying to say. OP said "I always was under the impression that it's bad practice to attach properties to the window object", and I was only attempting to reinforce the concept that it's impossible to avoid (to some extent). As with almost any concept, it can be used wisely, or abused :) – BLSully Jan 22 '15 at 19:36

1 Answers1

1

In general I would use the following approach...

if (typeof window['myApp']=='undefined') {alert('its okay.');}
else {alert('Error: native API added, have AJAX message server, email you.');}

...of course whether or not you should do this is subjective, I personally use...

var option = new function() {this.name = '';}
option.whatever = 'this string';
alert(option.whatever);//'this string'

...however I may rename it and revise it in the future as I do with all my code.

As Ingo Bürk points out in the comments it seems ultimately everything is an object child of the window object, the only difference between those objects is the context and how you can interact with them (e.g. you can not delete an object defined by var though you can delete window.myObject when it is defined as window.myObject = 1;.

For more in-depth information refer to the answer for 'Javascript global variables'.

Community
  • 1
  • 1
John
  • 1
  • 13
  • 98
  • 177
  • If executed in global scope, that would still leave you with `window['option']`. – Ingo Bürk Jan 22 '15 at 19:03
  • @IngoBürk Well yes, hence why I would rename it to something less generic. Adding an underscore between two words would be a great way to go sans frameworks (I only do real code) since object names never have any spaces or delimiters. As long as there is object detection to determine if an object with that name doesn't exist you'll be okay and on top of that if you have the client use AJAX so you can have the server email you the first (if ever, subjective to how effectively you name it) instance something with the same name is defined then you'll be able to stay on top of it. – John Jan 22 '15 at 19:12
  • My point is that your answer has no point. It suggests that using local variables avoids the issue, but this is just not true in the global scope (despite being absolutely correct in saying globals should not be used). It's like the *essential* part of what you are (probably) trying to say is actually left unsaid in your answer. – Ingo Bürk Jan 22 '15 at 19:14
  • Additionally you may want to consider setting something like `var ts = new Date().getTime(); `window.['my_object_'+ts]` as the likelihood of someone using that is even more astronomically unlikely. – John Jan 22 '15 at 19:14
  • @IngoBürk Well that is the thing, if you can't set anything on the same tier as the `window` object then *everyone* is dealing with the same problem; it comes down to how unique your naming scheme is. – John Jan 22 '15 at 19:16
  • I'm not disagreeing with what you *intend* to say. I'm trying to tell you that your answer does not really convey that information. – Ingo Bürk Jan 22 '15 at 19:17
  • @IngoBürk Yeah, updated the answer. The question *might* be a duplicate on top of that, subjective to *how* it's been asked (presuming it has). Got to love JavaScript. – John Jan 22 '15 at 19:24
  • Thanks for the answer & the interesting discussion – also thanks @IngoBürk. I think I understood what you are saying – since everything exists in the global namespace, at least one property needs to be attached to it. In your example, that is `option`, but since it's an anonymous function it can contain **all** other properties, making `option` the only variable visible in the global namespace. That way, there is only one point where you can clash with other code – on the variable name, that holds all other options. Is that correct? – Sven Jan 22 '15 at 19:40
  • @Sven Correct, so if you choose a *single well named* property *and* you ensure that you'll get email notifications from the server (via client AJAX request to notify the server to do so) you'll always be able to ensure there are no naming conflicts or that if there are be able to act to resolve them so only a small handful of people using bleeding edge browser versions will encounter any issue. You can go *even further* by incrementing `new Date().getTime()` until an unused name is encountered (be sure to `break;` at a reasonable limit though). :-) – John Jan 22 '15 at 20:18
  • @Sven Thank you asking an interesting question and for accepting. – John Jan 22 '15 at 20:45