I think I know the answer but... is there any way to prevent a global variable from being modified by later-executing ? I know global variables ar
Javascript is object oriented, rather than making the variable $public static, consider making it private and then properly providing an acessor method for getting, but not setting it.
e.g.
private var myGlobal : myType;
function GetMyGlobal() : myType
{
return myGlobal;
}
There are ten different ways to solve any given problem, your way and the right way.
Choose a variable name which is unlikely to be overwritten by accident and trust the programmer to not do stupid things. JavaScript is not Java, so don't pretend it was.
Also, if what you really want to do is namespacing, use a self-executing function literal:
var myLibName = (function() {
var aPrivateVar;
function aPrivateFunction() {}
function accessorForPrivateVar() {
return aPrivateVar;
}
// public interface:
return {
getPrivateVar : accessorForPrivateVar
}
})();
Conventions and good Documentation.
You can prefix your "immutable" variable with two (or more) underscores to indicate that is something not meant to be used by others and to avoid other people's variables clashing with yours.
Maybe creating a 'namespace' like __GLOBALNAMESPACE
(Ugly name, I know) and then adding your variables into it (eg __GLOBALNAMESPACE.my_var
) and creating a method like this one to retrieve them:
getVariable(string name){
return __GLOBALNAMESPACE[name]
}
Just my 2 cents.
what about this code by http://ejohn.org/ @ http://ejohn.org/blog/ecmascript-5-objects-and-properties/
Look like this actually works... I run some "little" testing and freeze the variables and attributes.
Freezing an object is the ultimate form of lock-down. Once an object has been frozen it cannot be unfrozen – nor can it be tampered in any manner. This is the best way to make sure that your objects will stay exactly as you left them, indefinitely.
Object.freeze = function( obj ) {
var props = Object.getOwnPropertyNames( obj );
for ( var i = 0; i < props.length; i++ ) {
var desc = Object.getOwnPropertyDescriptor( obj, props[i] );
if ( "value" in desc ) {
desc.writable = false;
}
desc.configurable = false;
Object.defineProperty( obj, props[i], desc );
}
return Object.preventExtensions( obj );
};
Little example
var config = (function (__name) {
name: __name
var _local = {
Server: "SomeText",
ServerDate: "SomeServerDate",
JSDate : Util.today(),
User : {
user: "1stUser",
name: "",
email: ""
},
}
/*Private Methods*/
function freezing(__array) {
$.each(__array, function (_index, _item) {
Object.freeze(_item);
});
}
/*Public Methods*/
var $r = {};
$r.info = function () {
return _local;
}
freezing([
_local,
_local.User
]);
_local.User.user = "newUser"; //Trying to assing new value
//Remain with the same value as first declaration
console.log(_local.User.user); //--> "1stUser"
return $r;
})("config");
If you can use typescript, you can mark properties as readonly
Instead of declaring all such variables in the global scope, you could have one global object wrapping around those variables. Using Object.defineProperty()
and/or Object.defineProperties()
with the writable
flag set to false
, you can have an immutable variable.
var myObj = {};
Object.defineProperty(myObj, 'myVar', {
value: someValue,
writable: false
});
Or you could just use the const keyword
const MY_VAR = 10;