Easy accessible variable that isn't in the Global scope - javascript

I am building a game with the CreateJS library. In the current build I save a lot of my variables and objects in the Global scope, which is really neat and makes it easy for various extended classes to reuse SpriteSheets etc.
I am looking for a way to NOT use the global scope. Obviously I can pass the spritesheet, or a class which contains the spritesheet as a parameter to all displayobjects I make, but I was hoping there was a more clever way of doing this.
Any suggestions or tips on how to achieve this would be helpful.

You may want to use a module:
var main = (function(){
var myPrivateVal1 = "Something";
var myPrivateVal2 = 56;
var myVeryPrivateVal = 3;
//Return only what you want to expose
return {
myPublicVal: 123,
getVal1: function(){
return myPrivateVal1;
},
getVal2: function(){
return myPrivateVal2;
},
doCalculation: function(){
return myVeryPrivateVal * myPrivateVal2;
}
}
})();
console.log(main.myPublicVal); //123
console.log(main.myPrivateVal1); //undefined
console.log(main.myPrivateVal2); //undefined
console.log(main.myVeryPrivateVal); //undefined
console.log(main.getVal1()); //Something
console.log(main.getVal2()); //56
console.log(main.doCalculation()); //168
Here you have one global variable main, which is the module that exposes what you need to expose, but still keeps track of the variables needed.
See this JSFiddle.

Related

js - avoiding namespace conflict

Thus far I've worked only with relatively small projects (and mostly alone), but this time I have to collaborate with other programmers... basically because of that I must plan the structure of the website very carefully for the avoidance of spending hours debugging the code.
At this point I suppose doing that in the following manner. I divide my code in modules and store each module in a separate file inside an object (or a function) with a made-up name (lzheA, lzheB, lzheC etc.) to avoid conflicts whether an object with the same name was used in an another piece of code. When the document is loaded, I declare a variable (an object) that I use as a main namespace of the application. Properties of the object are the modules I defined before.
// file BI.lib.js
var lzheA = {
foo: function() {
},
bar: function() {
},
}
// file BI.init.js
function lzheK() {
BI.loadPage();
}
// file BI.loadPage.js
function lzheC() {
var result = document.getElementById('result');
result.innerHTML = "that worked";
}
// and so on
var lzheA,lzheB,lzheD,lzheE,lzheF,lzheG,lzheH,lzheI,lzheJ;
// doing the following when the document is loaded
var BI = {
lib: lzheA,
menu: lzheB,
loadPage: lzheC,
customScripts: lzheD,
_index: lzheE,
_briefs: lzheF,
_shop: lzheG,
_cases: lzheH,
_blog: lzheI,
_contacts: lzheJ,
init: lzheK,
}
BI.init();
https://jsfiddle.net/vwc2og57/2/
The question... is this way of structuring worth living or did I miss something because of lack of experience? Would the made-up names of the modules confuse you regardless of the fact that each one used only twice - while declaring the variable and assigning it to a property?
I consider the namespaces a good option when you want to modularize applications in Javascript. But I declare them in a different way
var myModule = myModule || {}; // This will allow to use the module in other places, declaring more than one specificComponent in other js file for example
myModule.specificComponent = (function(){
// Private things
var myVar = {};
var init = function() {
// Code
};
return {
init: init // Public Stuff
};
})();
If you want to call the init method, you would call it like this
myModule.specificComponent.init();
With this approach, i guarantee that the module will not be overwritten by another declaration in another place, and also I can declare internal components into my namespaces.
Also, the trick of just exposing what you want inside the return block, will make your component safer and you will be encapsulating your code in a pretty way.
Hope it helps

Best practice to organize extension methods in JavaScript

I have a bunch of extension methods of String and other JavaScript types, they now reside in global namespace.
What is the best practice to organize those extension methods? Should I encapsulate them inside a namespace? If yes, how to achieve that? Thanks!
Namespace your JavaScript if you need to refer to it elsewhere.
// define your global namespace
var Extensions = Extensions || {};
// add modules to it
Extensions.String = function() {
var myPrivateProperty = 2;
var myPublicProperty = 1;
var myPrivateFunction = function() {
console.log("myPrivateFunction()");
};
var myPublicExtension = function() {
// this extension is being called, now what?
console.log("myPublicExtension()");
};
// this object will be returned, giving access to public vars/methods
return {
myPublicProperty: myPublicProperty,
myPublicExtension : myPublicExtension
};
}();
console.log("Calling myPublicExtension()...");
Extensions.String.myPublicExtension();
Anonymously scope JavaScript if you’re never going to call it elsewhere.
// This will keep your namespace clean
(function() {
// here you can define your modules, functions, etc..
var x = 123;
console.log(x);
// to make something global you can define it like
window.globalVar = 5;
}());
Or you can extend the native javascript objects with prototype like this:
String.prototype.myExtension = function(p1, p2) {
// here is your function
return this + p1 + p2;
}
This way you don't need to define namespaces and you can call your extensions directly from any object you extended:
var otherString = "mystring".myExtension(" is", " great!");
console.log(otherString);// mystring is cool
you can do that with any object in javascript
EDIT:
Prototype extensions don't pollute global namespace, because they are accesible only through the object you extended.
If you have many extensions consider taking them into a file like extensions.js, then add it to your pages whenever you need those extensions. This way extensions.js can be cached by the browser and will be loaded faster
There are 2 ways of doing that:
Encapsulating in a namespace (I think the bare minimum to keep things tidy). A custom namespace ie:
window.MyNameSpace.trim = function(str) {
return str.replace(/^\s+|\s+$/g, "");
}
(replace MyNameSpace with a single letter! R for Raphael, L for Leaflet, etc)
Extend prototypes! Lots of people will disagree with that but I see no harm if it is your site and you don't override/conflict with anyone else code:
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, "");
};
I find this "cleaner" since you don't pass unnecessary arguments around... but again, it is a matter of opinion... This will work for any build-in type. The rest I think should follow #1
DISCLAIMER: Code from This post

JavaScript design pattern

can someone please explain to me the following JavaScript design pattern example and what it's trying to accomplish?
var Knockback = { };
Knockback.Observables = (function () {
function Observables(model, mappings_info, view_model) {
this.model = model;
this.mappings_info = mappings_info;
this.view_model = view_model;
//logic in here
}
Observables.prototype.destroy = function () {
//logic in here
this.view_model = null;
this.mappings_info = null;
return this.model = null;
};
return Observables;
})();
Knockback.observables = function(model, mappings_info, view_model, options) {
return new Knockback.Observables(model, mappings_info, view_model, options);
};
Knockback is a namespace. Values are stored inside Knockback so they do not clash with any global variables.
Observables is a constructor sitting inside Knockback. All of the logic is inside a closure ((function () {})()) for modularity
observales is used as a method of returning an instance of Observables, This is a way that people can use whats known as "scope safe constructors". In javascript if you call a constructor without new, then the this object defaults to the window, polluting your global namespace again.
I'm not sure how much you know about javascript, but I hope this helps.
-------------------------------- updated --------------
1) The closure functions the same as without a closure, that is correct (At the time of my answer i didnt know that there were no "private" variables). But this pattern also allows you to place this constructor wherever you please. Imagine if the namespace (Knockback) name changed to KB. You could place the constructor there without even needed to change a line of code inside the closure.
2) The Knockback.observer function may be a bloat (which i personally dont think it is) but the "scope safe" factor is considered a best practise. consider:
var standardCorrectInvokation = new Knockback.Observer('model', 'mappings_info', 'view_model');
var aboutToLooseMyJobInvokation = Knockback.Observer('this', 'is', 'un-intuative');
//goodbye global namespace
alert(window.model); // this
alert(window.mappings_info); // is
alert(window.view_model); // un-intuative
//goodbye job at reputable web firm
Id like to point out that the boys as ES5 camp fixed this problem, but strict mode is not implemented in all browsers yet (IE.. ahem ahem)

My own mini-framework is not compatible with some projects

I failed to create a mini-library with some useful functions that I have found over the Internet, and I want to use them easily by just including a file to the HTML (like jQuery).
The problem is that some vars and functions share the same name and they are causing problems.
Is there a better solution to this instead of giving crazy names to the vars/funcs like "bbbb123" so the odds that someone is working with a "bbbb123" var is really low?
I would put all of your functions and variables into a single object for your library.
var MyLibrary = {
myFunc: function() {
//do stuff
},
myVar: "Foo"
}
There are a few different ways of defining 'classes' in JavaScript. Here is a nice page with 3 of them.
You should take one variable name in the global namespace that there are low odds of being used, and put everything else underneath it (in its own namespace).
For example, if I wanted to call my library AzureLib:
AzureLib = {
SortSomething: function(arr) {
// do some sorting
},
DoSomethingCool: function(item) {
// do something cool
}
};
// usage (in another JavaScript file or in an HTML <script> tag):
AzureLib.SortSomething(myArray);
Yes, you can create an object as a namespace. There are several ways to do this, syntax-wise, but the end result is approximately the same. Your object name should be the thing that no one else will have used.
var MyLibrary = {
myFunc: function() { /* stuff */ }
};
Just remember, it's object literal syntax, so you use label : value to put things inside it, and not var label = value;.
If you need to declare things first, use a wrapping function to enclose the environment and protect you from the global scope:
var MyLibrary = (function() {
var foo = 'bar';
return {
myFunc: function() { /* stuff */ }
};
})(); // execute this function right away to return your library object
You could put all of your library's functions inside of a single object. That way, as long as that object's name doesn't conflict, you will be good. Something like:
var yourLib = {};
yourLib.usefulFunction1 = function(){
..
};
yourLib.usefulFunction2 = function(){
..
};

accessing my public methods from within my namespace

I am in the process of making my own namespace in JavaScript...
(function(window){
(function(){
var myNamespace = {
somePublicMethod: function(){
},
anotherPublicMethod: function(){
}
}
return (window.myNamespace = window.my = myNamespace)
}());
})(window);
I'm new to these kinds of advanced JavaScript techniques and i'm trying to figure out the best way to call public methods from within my namespace. It appears that within my public methods this is being set to myNamespace.
Should I call public methods like...
AnotherPublicMethod: function(){
this.somePublicMethod()
}
or...
AnotherPublicMethod: function(){
my.somePublicMethod();
}
is there any difference?
The way I see it, if you use this you're using a direct reference to the object, whereas if you use my, the interpreter would need to traverse the scope chain until it finds my as a property of window.
But there may be arguments the other way as well.
EDIT:
I should note that since this is determined by how the function is called, it would require that the Activation object be that object.
So this would work:
my.anotherPublicMethod();
But this would not:
var test = my.anotherPublicMethod;
test();
If that's a possibility, then you should use my, or some other direct reference to the object. You could reduce the scope chain traversal by maintaining a reference to the object. Your myNamespace variable should work.
A little off topic, but I'd also note that your code won't work the way it is.
This line:
return (window.myNamespace = window.my = myNamespace)
...doesn't have access to the myNamespace variable.
Perhaps you meant something more like this?
(function(window){
window.myNamespace = window.my = (function(){
var myNamespace = {
somePublicMethod: function(){
},
anotherPublicMethod: function(){
}
}
return myNamespace;
}());
})(window);

Categories