I have a bunch of functions in my script which resides in a .js file.
How can avoid conflicts with the names of my functions within the same page if some other script written by some other guys use the same function names as in my script ?
Is there a way to do this?
If you don't need access to those functions outside of your script you can wrap the whole script in an immediately invoked function expression:
(function () {
// Your code here
}());
This introduces a new scope, so any declarations within it are not visible outside of it.
If you do need access outside of that scope, expose your functions as methods of a "namespace":
var YourStuff = (function () {
// Private functions etc...
// Expose public methods
return {
someMethod: function () {}
};
}());
By taking this approach you only introduce a single global identifier, reducing the chances of a conflict. You can call the method as follows:
YourStuff.someMethod();
Use namespaces..
var company = {};
company.doSomething = function() {
};
company.project = {};
company.project.submodule = {};
company.project.submodule.doSomething = function() {};
Related
I'm creating a wrapper for an API that will be used in a couple different applications.
I'm using a global object and placing the various functions into that object as different keys. So I'll have:
window.globalContainer = {
APIEndpoint1: function(){
make API call and resolve result
},
APIEndpoint2: function(){},
...
}
All the meat of the API calls are directly in the functions. That is, you could go to window.globalContainer.APIEndpoint1 from the console and see the entire function.
Is this generally bad practice for something that's used across multiple applications and acts as a helper library? Or is this acceptable? I looked at jQuery in the console and it seemed to do much of the same. If it is frowned upon, how do I implement private functions within the global object?
A good place to start is anonymous closures:
(function (global) {
var foo = global.foo || {};
//accessible
foo.publicVar = 5;
foo.publicFcn = function (a, b) {
privateFcn(a, b);
...
};
//not accessible
var privateVar = 5;
function privateFcn(a, b) {
...
}
global.foo = foo;
})(window)
With these you can pretty intuitively build a library and not pollute the namespace.
You explicitly say which variables and functions you want to be made accessible.
You can use an IIFE to implement private functions/properties.
window.globalContainer = function () {
//what ever you define here is not accessible outside. Only the API in
//the returned object is accessible outside
function private1() {
make API call and resolve result
}
return {
APIEndpoint1: function(){
private1();
},
APIEndpoint2: function(){},
...
}
}();
I am reading A JavaScript Module Pattern, and wondering why bother to do the module assignment by firing an immediate anonymous function call like this:
YAHOO.myProject.myModule = function () {
return {
myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.",
myPublicMethod: function () {
YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
}
};
}();
instead of directly assign the object to YAHOO.myProject.myModule like this:
YAHOO.myProject.myModule = {
myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.",
myPublicMethod: function () {
YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
}
};
In that example, there isn't any point. You didn't read enough of the document you linked to.
Section 3 is Add "private" methods and variables in the anonymous function prior to the return statement., and that demonstrates why you would want to use an IEFF here.
It is so you can define local variables which are accessible to the functions you are making public, but aren't directly accessible themselves.
Suppose there is a global variable which is a function
function MyClass(){}
and there are methods of this class such as
MyClass.func1 = function()
{
}
I want to ensure that YUI compression and obfuscation works without putting entire class inside a closure like
(function () {
function MyClass(){}
MyClass.func1 = function()
{
}
})();
Is there a way to make YUI compression work without doing this?
Well, I suppose you could wrap it in an anonymous function before compressing it, and then just remove the anonymous function after.
Also make sure you're using prototype ;)
(function () {
function MyClass(){}
MyClass.prototype.func1 = function()
{
}
})();
Results in:
(function(){function a(){}a.prototype.func1=function(){}})();
And just take out the anonymous function:
function a(){}a.prototype.func1=function(){}
I saw in many source codes:
var me = this;
specially in Ext-JS 4 (JS framework). Why doing such thing? Is there any other reason or you just want for a variable to be called like "me" instead of "this"?
Thank you.
Usually so you can keep a reference to this inside a scope in which this refers to something else (like a callback function, for example).
Consider this example, in which the click event handler function has a different context to what you may expect (this doesn't refer to an instance of MyClass):
var MyClass = function (elem) {
this.elem = elem;
this.name = "James";
elem.addEventListener("click", function () {
alert(this.name); //oops
}, false);
};
Now consider this example, in which we store a reference to the value of this inside the constructor function, and use that inside the callback function:
var MyClass = function (elem) {
var me = this;
this.elem = elem;
this.name = "James";
elem.addEventListener("click", function () {
alert(me.name); //works!
}, false);
};
The callback function can refer to a variable that was declared in the outer function, even after that function has returned (the MyClass constructor returns as soon as it's executed the addEventListener). This is a demonstration of a closure.
Though of course closures are the more obvious reason for doing this, I just wanted to add that another reason can be to reduce the size of the minified version of a javascript file.
this as a keyword cannot be renamed in the process of minifying the file, while a local variable can. In other words, whenever you would use this (4 characters), instead a 1 character local variable can be used.
Consider the following example function of ExtJS's Ext.data.Store:
filterBy: function(fn, scope) {
var me = this;
me.snapshot = me.snapshot || me.data.clone();
me.data = me.queryBy(fn, scope || me);
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
(note there's no closure involved here)
and its minified version:
filterBy:function(b,a){var c=this;c.snapshot=c.snapshot||c.data.clone();c.data=c.queryBy(b,a||c);c.fireEvent("datachanged",c);c.fireEvent("refresh",c)}
(151 characters/bytes)
Now, let's compare it to the minified version if we did not assign this to a local variable:
filterBy:function(b,a){this.snapshot=this.snapshot||this.data.clone();this.data=this.queryBy(b,a||this);this.fireEvent("datachanged",this);this.fireEvent("refresh",this)}
(170 characters/bytes)
As you can see the version with a local variable only takes 88% of the size of the function which uses this each time instead.
Especially in big libraries this can reduce the file size quite a bit.
Setting me=this allows you to use the this variable from an outer scope in an inner scope.
var Outer= function () {
var me = this;
me.x = "outerx";
me.inner = {
x: "innerx",
displayValues: function () {
console.log(me.x); //outerx
console.log(this.x); //innerx
}
};
};
new Outer().inner.displayValues();
Basically this utilizes closure in javascript. Read this about closure.
It is used to carry the particular instance of this to function calls where this has a different meaning.
I'm trying to mimic static variables on a JavaScript function, with the following purpose:
$.fn.collapsible = function() {
triggers = $(this).children('.collapse-trigger');
jQuery.each(triggers, function() {
$(this).click(function() {
collapse = $(this).parent().find('.collapse');
})
})
}
How do I save the "collapse" object so it doesn't have to be "found" on each call? I know that with named functions I could do something like "someFunction.myvar = collapse", but how about anonymous functions like this one?
Thanks!
You can save your variable in the function, using either functioName.myVar = value or arguments.callee.myVar = value if you don't have the current function name.
arguments.callee is the current function you are in.
For anonymous function you could use a function that returns a function.
For instance:
var myAnonymousFunction = (function(){
var myFirstStatic = $("#anElement");
var anotherStatic = true;
return function(param1,param2) {
// myFirstStatic is in scope
// anotherStatic also
}
})();
Should work like a charm and you're assured initialisation code for statics is only executed once.
It seems that a better answer to this question is found elsewhere on Stack Overflow.
In short, you can actually give anonymous functions names without polluting the namespace, yet still allow self-referencing.
mything.prototype.mymethod = function myKindOfFakeName() {
myKindOfFakeName.called = true;
}
As long as you're assigning the function to a variable like that, you should be able to access it as $.fn.collapsible, and thus assign variables as $.fn.collapsible.myvar.