How can I create static variables in Javascript?
相关问题
- Is there a limit to how many levels you can nest i
- How to toggle on Order in ReactJS
- void before promise syntax
- Keeping track of variable instances
- Can php detect if javascript is on or not?
The following example and explanation are from the book Professional JavaScript for Web Developers 2nd Edition by Nicholas Zakas. This is the answer I was looking for so I thought it would be helpful to add it here.
The
Person
constructor in this example has access to the private variable name, as do thegetName()
andsetName()
methods. Using this pattern, the name variable becomes static and will be used among all instances. This means callingsetName()
on one instance affects all other instances. CallingsetName()
or creating a newPerson
instance sets the name variable to a new value. This causes all instances to return the same value.Working with MVC websites that use jQuery, I like to make sure AJAX actions within certain event handlers can only be executed once the previous request has completed. I use a "static" jqXHR object variable to achieve this.
Given the following button:
I generally use an IIFE like this for my click handler:
If you want to use prototype then there is a way
Doing this you will be able to access the counter variable from any instance and any change in the property will be immediately reflected!!
There are other similar answers, but none of them quite appealed to me. Here's what I ended up with:
So what I see with the other answers is that they don't address the fundamental architectural requirement of a static attribute in object oriented programming.
Object oriented programming actually has two different styles one is 'class based' (C++, C#, Java etc), the other is 'prototypal' (Javascript). In class based languages a 'static attribute' is supposed to be associated with the class and not the instantiated objects. This concept actually works much more intuitively in a prototypal languages like Javascript because you just assign the attribute as a value of the parent prototype like so.
And access it from every one of the objects that is instantiated from this constructor like so...
Now if you go ahead and change the
MyObject.prototype.staticAttribute
the change will cascade down to the child objects that immediately inherit it.However there are a few 'gotchas' that could significantly undermine the 'static' nature of this attribute, or just leave security vulnerability...
First make sure to hide the constructor from the Global namespace by enclosing it inside another function like the jQuery ready method
Second and lastly, even if you do this, the attribute is still editable from any of the other parts of your own script, so it could be the case that a bug in your code writes over the attribute on one of the child objects and detaches it from the parent prototype, so if you change the parent attribute it will no longer cascade and change the static attribute for the child object. See this jsfiddle. In different scenarios we could either
Object.freeze(obj)
to stop any changes to the child object, or we could set up a setter and getter method in the constructor and access a closure, both of these have associated complexities.It seems to me that there is not a perfect analogue between the class-based idea of a 'static attribute' and this Javascript implementation. So I think it might be better in the long run to use a different code pattern that is more Javascript friendly. Such as a central datastore or cache or even a dedicated helper object to hold all the necessary static variables.