62

Can I add any random attribute to 'window' object in javascript? Some thing like:

window.my_own_attr = "my_value"

Does it have any side effects with any libraries? And is it cross-browser compatible?

akkishore
  • 1,070
  • 1
  • 9
  • 17

7 Answers7

82

Can I add any random attribute to 'window' object in javascript?

Yes, just like you've shown.

Does it have any side effects with any libraries?

No, not unless you use a library which sets a property you then overwrite.

And is it cross-browser compatible?

Yes, completely.


Having said that, this practice is generally frowned upon. You could end up overwriting something you don't want to.

James Allardice
  • 164,175
  • 21
  • 332
  • 312
16

In all browsers, window is the javascript global namespace. Every property or method 'lives' in that namespace. So if you assign a property to window, it is in effect a global variable.

example:

window.myConstant = 5;

// note: a var declaration will be a window property too
// note 2: 'let' or 'const' will not be window properties
// below can also be done without 'var'.
var myConstantGlobal = 4;

console.log(`multiply(10) => ${multiply(10)}`);
console.log(`multiply() => ${multiply()}`);
console.log(`multiplyGlobalVar(10)) => ${multiplyGlobalVar(10)}`);
console.log(`multiplyGlobalVar() => ${multiplyGlobalVar()}`);
    
function multiply(val){
  return myConstant * (val || 1);
}

function multiplyGlobalVar(val){
  return window.myConstantGlobal * (val || 1);
}

You have to be cautious with javascript frameworks. For instance, if you declare window.JQuery, and use the JQuery framework, the JQuery namespace will be replaced by your assignment, rendering it useless.

KooiInc
  • 119,216
  • 31
  • 141
  • 177
4

Yes, you can, but in general you shouldn't.

The window object is also the JS default "global" object, so all global variables get added there.

You're unlikely to break anything unless you overwrite a property that's already there, but it's considered bad practise to dump variables on window, or otherwise create lots of global variables.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
4

I won't repeat what others have said re: the hackyness of this practice. But it can be incredibly useful when using a rigid framework like Angular mixed with vanilla HTML / JS (or jQuery) code. Which is also hacky and frowned upon, but sometimes there are good reasons, like if you have lots of pre-existing JS code that will be challenging to integrate into the framework.

The more interesting question to me is HOW to make use of the ability to add properties to the global window object. There is a pattern I use when I want to expose the methods of an Angular provider (service) to code that otherwise would be unable to inject the service, probably because it runs outside of the Angular DI framework. The way I do it is as follows:

  1. Define your service as a provider in your top level module.
  2. In the constructor or onInit of app.component.js (or whatever your top level component is that imports the provider), inject the provider normally, perform any one time initialization that it needs, and then call window['MyServiceName'] = this

Assuming you have designed the provider to follow a Singleton pattern, your provider's methods can now be safely called from anywhere. A non-Angular script need simply call window['MyServiceName'].methodName()

Sam Rahimi
  • 86
  • 5
0

That 'll work fine, no conflict with any library until used same variable name, will work in all browsers, but not recommended as this will create global JS variable.

Riz
  • 9,703
  • 8
  • 38
  • 54
  • 'window' is anyway a global object. So thats ok I guess? – akkishore Oct 05 '12 at 09:10
  • in your case you can directly access `my_own_attr` without `window.`, that makes it global and can conflict with other variable with same name. – Riz Oct 05 '12 at 09:11
0

In IE if an element has an id, then that node is accessible on the window object as a property:

<div id="num"></div>

alert(num); //Element

num = 3; //throws exception

var num = 3; //ok

Kernel James
  • 3,752
  • 25
  • 32
  • Just to clarify, this comment was targeting IE6 ~ IE9 (which was popular back in 2012) and is no longer valid for newer versions of IE (Edge). – Kernel James May 13 '22 at 03:34
0

As pointed out by others yes you can and yes it means adding "global variables".

Having global variables is not best practice but sometimes it is the simplest thing to do. For instance if you use IFrames and want the child-window to access some property of the parent window. Such a property must be "global" for a child to access it. But this also shows that it is not "truly global", it is just a property of a specific window. But it can conflict with other property-names such as names of functions defined in the same window, perhaps by some libraries you use.

So we know global variables are bad. If we decide to use them anyway is there anything we can do to minimize their badness?

Yes there is: Define a SINGLE global variable with a more or less unique name, and store an OBJECT into it. Store all other "variables" you need as fields of that single object.

This way you don't need to ever add more than a single global variable (per window). Not TOO bad.

Name it more or less uniquely so it is unlikely to conflict with anybody else's single global. For instance you could use your name + 's' as the variable name:

window.Panus  = {}; 

:-)

Panu Logic
  • 2,193
  • 1
  • 17
  • 21
  • 1
    In ES6 you can take it further and define such a global variable as const. Then if someone else tries to overwrite it you should get an error-message telling what is going on – Panu Logic Nov 19 '18 at 15:49