Enclosing js function between ()? [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between (function(){})(); and function(){}();
I have seen it a lot by google:
(function(){/*code*/})
Why they enclose their function inside the parethesis?
Which is the difference between:
function(){/*code*/}
?
Edit
Ok the questions should have been this:
Why they enclose their code into this:
(function(){/*code*/})();
Instead to write the code directly into the js flow?
Are there any benefits, different behaviour?

I usually use immediate functions to control the variable scope so as not to pollute the global name space. It's a very useful pattern.
(function (window, $, undefined) {
// This pattern gives you the following benefits:
// * all variables defined in here are private
// * can safely minify global variables: window, jQuery & undefined
// * ensures that window, $, undefined mean what you expect
// * global variables are localized so lookups are faster
}(this, jQuery));
So even if someone does window = ‘Bob’ or the shortcut $ doesn’t equal jQuery but instead is the Prototype library, the code inside this immediate function will still work correctly. While you may think to yourself “I’d never set undefined to something else”, keep in mind you’re not the only one putting code into the page; you can’t afford to have a poorly written ad script from DoubleClick bringing down the site, especially when it is so easily prevented.
JavaScript’s global scope is like a public toilet. You can’t always avoid it, but try to limit your contact with surfaces.

what you see is a self executing function:
var x = (function(bar){
return bar;
})('foo')
alert(x);

It's usually done to force the parser to treat it as a function expression and not a declaration.

This is because usually the code looks like this:
(function(){/*code*/})();
The reason for the extra parenthesis is that this is not legal syntax:
function(){/*code*/}();

It's needed for immediate functions as #daniellmb said. See explanation of expression closure for more information.

Related

What does ;(function(global,$,_){ }(app,jQuery,_)); mean? [duplicate]

This question already has answers here:
How does the (function() {})() construct work and why do people use it?
(15 answers)
Closed 9 years ago.
In one JavaScript file, the script was wrapped into this, why wrap codes into this? Any reference to this? Why define Basepage=global.Basepage?
;(function (global,$,_) {
var Basepage=global.Basepage = Backbone.View.extend({});
}(app,jQuery,_));
By setting a var Basepage, Basepage will become a local variable in that function, and they don't need to write global.Basepage for any further references. Organization like this has several benefits, and I'll try to list each.
Any variables inside the function will be inaccessible to other parts of the code. This is very useful if you declare a common name like var x or var element and don't want it to get mixed up with others as a global variable.
Inside the function, 'app' is referred to as 'global'. Setting 'global.Basepage = Backbone.etc...' means that after that function is executed, app will have BasePage as a property.
Some javascript loader-frameworks depend on this style to be able to initialize a module after all of its dependencies (like JQuery) have loaded.
It is a method of namespacing. With this you get the effect on adding a single variable into the global namespace and you can access it to access other methods and variables.
What it is doing is self executing the function when the code is read, and when it executes, app, jQuery, and _ are passed in as variables to the function, which are what the parameters take on. global = app $ = jQuery _ = _.
This gives you a good way to encapsulate functionality without polluting the global namespace and decreases the risk over overriding variables that have the same name in your application.

How do I prevent accidental global name space pollution with javascript eval?

I am writing a simple REPL (Read, Evaluate, Print, Loop) implementation in JavaScript. I am able to isolate code and calling context like so:
var sandbox = {
// Allow the input code to use predefined helper functions
// without the preceding use of the this keyword.
helper_fn: function() { alert("foo"); }
};
var func = new Function("with (this) { " + user_inputed_code + " }");
func.call(sandbox);
Now it closes the user_inputed_code so that this referers to sandbox and if the inputted code accesses or mutates this it is affecting sandbox.
However, I noticed that if the imputed code were to accidentally forget to preface a variable assignment with the keyword var that the global namespace get polluted.
Is there anyway to prevent this? If so how (maybe a regexp?)? Is there a better way to approach this?
I'm going to provide two completely different approaches from what others discussed here. They are both drastic, and are useful when you want to relatively isolate your environment.
The easiest technique that works in all browsers is to probably create an iframe, and append script tags to it. (Note, a really overzealous iframe can still get past that if they're in the same domain, at least in older browsers). I discuss that in this question.
Use web Workers, which have an isolated environment by default and have no access to the global object of the main execution thread. I discuss that in this question.
More specifically, if you're building a REPL take a look at this answer where we discuss and I explain how to eval code in the same scope but outside the global scope, using the first approach of iframes.
(I assumed a browser, in node you can simple use the vm module and select the context in runInContext)
Turns out there is a way with "use strict" and without Object.freeze. You have to manually replace the global namespace with your own sandbox object:
var sandbox, module, func, output;
// Empty object or with defined methods / properties
// you want to expose as globals.
sandbox = {};
// A reference to an object you WANT to provide safe
// access to. In this example it's just an empty object.
module = {};
// A better version of eval:
func = new Function("module", "with(this){return(function(module,global,window){\"use strict\";return eval(\"" + code + "\");})(module,this,this)}");
output = func.call(sandbox, module);
This code allows global and window to refer to a sandboxed object instead of the global name space. It masquerades the variables global and window as the sandbox object and the use of "use strict" will cause it to throw an exception if the input missed the use of var. It also wraps the function in a with statement to make the methods and properties defined in the sandbox object to work as if they were preceded by this.. To see an implementation example (with test specs) check out this gist.
Thank you all for your ideas. Hope this answer helps others.

Basic Javascript Function

I am trying to learn more about Javascript, I have been coding with PHP and making web application for years, I have basic knowledge of JS, most of the JS I have used has been already coded and me just plugging it in until recently, in the past years I have been able to do a lot with jQuery.
I have noticed that Stack Overflow uses jQuery more then most sites I have seen, it is beautiful all the JS functionality they have here.
So a basic question, Stack Overflow uses StackExchange in front of most of the JS code that I have seen on here. What exactly is that doing? To me I would want to say it is like a Class name but I read JS does not have classes.
Here is an example code
StackExchange.debug.log("no cache breaker for " + q);
Can you break this down for me to explain what the StackExchange, debug, log are?
I mean I can tell that log must be a function call but the others?
PS) Please don't move this to META as it is a JS question and not specific to StackOverflow
Also feel free to edit the question title and delete this line if you can think of a better title, thanks
Think of StackExchange as something much like the global jQuery function, "$" (or "jQuery"). It's just a global reference to an object that has functions and other properties.
Thus, "debug" is a property of the global "StackExchange" object, and in turn "log" is a property of the "debug" object. In this case, the "log" property references a function, which clearly is a debugging tool.
It's a debatable point whether JavaScript has "classes" or not, but it definitely has objects. (By "debatable" I mean it's a subject that fills an endless stream of blog posts and Stackoverflow questions :-)
That is, in fact, basic JavaScript. There's nothing super fancy or tricky about it.
Namespaces.
this may be relevant
How do I declare a namespace in JavaScript?
EDITED FOR CLARIFICATION
Before I say ANYTHING, please see How Classical Object-Oriented Programming Translates to Javascript. This is VERY important to understand. Now, that being said, I'll continue :)
Javascript has the unfortunate characteristic that you have to understand the run-time environment very well in order to make sense of why certain syntax is chosen over another that expresses the same thing (in theory). One of the main caveats of the run-time environment of javascript is that it is very easy to get things into the global space unintentionally. Here's two quick examples (these examples assume that you don't have any other code written):
/*
* Example 1
* This example uses 'object literal notation'.
* A link to an article about this is below the example.
* This example shows how easy it is to get into the global space just by
* not declaring variables properly.
*/
var myObj = {
myMethod: function() {
test = 'test'; // oops! now the variable test is in the global
// function space :(
// to avoid this, use var test = 'test'; to keep
// test in the scope of myMethod
}
};
Read about object literal notation.
/*
* Example 2
* This example shows how the infamous 'this' can be misused to accidentally
* get into the global space.
*/
var myConstructor = function() {
this.test = 'test';
};
var myObj1 = new myConstructor(); // 'this' will by 'myObj1'
var myObj2 = myConstructor(); // 'this' will by the global object :(
To see why Example 2 is true, see this.
One of the ways you avoid all of these headaches is by following good patterns that control access to the global scope. As some of the answers have pointed out, you can think of the StackExchange object as being used for namespacing purposes, but in reality, it's most often used to also avoid the problem listed in above example, as well prevent things such as name hoisting. In addition, you can make this 'namespacing' object also behave more like a traditional object from other classical OOP languages if you are intelligent in using closure scopes (taking advantage of the fact that all scopes in javascript are bound to functions, and functions in javascript are first-class data objects). Also, because the global space is so dangerous, it's best to "be a good DOM citizen" and only create one object in the global space that encapsulates all of your logic and data.
Joel and jeff are probably actually setting up closure scopes to do information hiding the javascript way. The below is just an example:
StackExchange = (function() { // give StackExchange it's own scope to prevent
// name hoisting and also to allow for private
// data
var version = '1.0.0'; // version only seen inside function scope
return { // return an object that will become 'StackExchange' and whose
// methods have access to this function's scope (closure)
debug: (function() {
// set up logging function that will be determined based on
// 'someCondition' (not defined in this code)
var loggingFn = (someCondition) : console.log ? alert;
return { // return obj with access to this function scope
log: function(strToLog) {
loggingFn.call(this, strToLog);
}
};
})(), // immediately execute to make object with 'debug' scope access
getVersion: function() {
return version; // this function has access to StackExchange
// scope; therefore, version will be available
}
};
})(); // immediately execute to make object with 'StackExchange' scope access
For more information, see name hoisting and scoping. Also, please read about Prototypical Inheritance in Javascript to understand patterns used to avoid global scoping problems.
This code would define the object necessary to perform the call shown in your example. As you can see, it simply defines an object containing more objects finally containing one or more functions.
var StackExchange = {
debug: {
log: function(whatever) { /* some code */ }
}
};
StackExchange.debug.log("no cache breaker for " + q);
StackExchange is a global object and debug is an another object which is a property of StackExchange object and it has a function called log.
Read more about Objects in JavaScript here.

HTML5 drag & drop events in Javascript

I followed a little tutorial on Drag & Drop in HTML with Javascript, found here:
http://www.html5rocks.com/tutorials/dnd/basics/
The problem is, I'm working with an in-house style restriction. Meaning all documents have to be written to standards that everyone here uses.
For Javascript, one of them is to always write functions in the object-notation.
I.e.
var myFunction = function() {}
instead of
function myFunction() {}
In this tutorial, the events for the HTML5 drag & drop are added via the addEventHandler() function. This requires you use the normal notation, because if you use the object-notation, the addEventHandler() function trips over it for some reason.
I tried re-writing everything to be like this, without addEventHandler:
myElement.dragstart = function(e) {}
But non of it worked. Using the normal notation with addEventHandler however, everything works like a charm.
I just wanna make sure: am I overlooking something or should this work? Part of me suspects this is just not supported properly yet and you need to use addEventHandler. Is this the case?
Setting the dragstart property vs using addEventHandler('dragstart', ...) is not just a matter of notation. You can and should stick with addEventHandler. There should be no problem, however, using this "style:"
var myFunction = function() {}
myElement.addEventListener('dragstart', myFunction, ...);
Edit
Okay, so this doesn't directly answer the question, but I feel it does need to be addressed in this context.
Writing
var myFunction = function() {}
instead of
function myFunction() {}
is not any sort of "object notation." The first is a function expression, since it's part of an AssignmentExpression. The second is a function declaration. What's the difference? kangax explains it really well:
First of all, function declarations are parsed and evaluated before any other expressions are. Even if declaration is positioned last in a source, it will be evaluated foremost any other expressions contained in a scope.
...
Another important trait of function declarations is that declaring them conditionally is non-standardized and varies across different environments. You should never rely on functions being declared conditionally and use function expressions instead.
Do the people who set the JavaScript code standards in-house really understand the subtle differences?
Point number 1: that's a stupid rule. There are two ways of naming a function for a good reason, and ignoring that to specify one style is fairly dim, IMO.
Your problem is, I think, that your function hasn't been defined by the time you get to addEventHandler. This is because of something called "hoisting". In this process, functions named with the function myFunction() {} syntax are "hoisted" to the top of the function. So if you invoke them anywhere in the function, the function will work. For instance, this will work:
el.addEventListener('click', foo);
function foo() {}
Functions named in your organisation's style, however, are not hoisted. The variable declaration is, but the value is not set until that line of code is reached. So this will not work:
el.addEventListener('click', foo);
var foo = function() {};
The easiest way to get around this would be to move all your function definitions to the top of the scope, unless there is a good reason to define them later. So this will work:
var foo = function() {};
el.addEventListener('click', foo);

How do jQuery's namespaces work? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What does this JavaScript/jQuery syntax mean?
I specifically mean when you do this:
(function ($) {
...
})(jQuery);
I've never seen that kind of syntax before. How does the function get called? I understand when you do it like this:
jQuery(function ($) {
...
});
because the function is being passed to jQuery, and jQuery can just run any function passed as a parameter when the DOM's ready, but the first one's different.
Duplicate of What does this JavaScript/jQuery syntax mean?
I'll post my answer here, though seeing as Jeff Attwood seems to want us to embrace duplication: (https://blog.stackoverflow.com/2010/11/dr-strangedupe-or-how-i-learned-to-stop-worrying-and-love-duplication/)
This convention is used when writing plugins to ensure there is no confilict with other Javascript libraries using the $ notation, whilst ensuring the plugin author can still use this notataion:
(function($){
...
})(jQuery);
The author is declaring an anonymous function with a single parameter ($), then immediately calling it and passing the jQuery object to it. This ensures the function is called and that everything in it is defined.
A longer notation might be:
function MyDefs($){
...
}
MyDefs(jQuery);
Although that would create a variable MyDefs in the global namespace. The anonymous function pattern leaves the global namespace empty, avoiding conflicts.
It's an anonymous function. When you write:
(function ($){
..
})(jQuery);
It is mostly equivalent to:
function the_function($) {
..
}
the_function(jQuery);
The only difference being that the first does not create a function called the_function and therefore created no risk of accidentally overwriting an existing function or variable with that name. And of course, all of it is equivalent to:
function the_function() {
var $ = jQuery;
..
}
the_function();
The point of this construct is that any variables defined inside the_function are local and therefore cannot accidentally overwrite any variables or functions in the global scope. For instance, the code inside the function uses $ to represent the jQuery object, but this would conflict with other libraries that use $ as well (such as Prototype). By wrapping the usage of $ inside a function, the Prototype code outside the function remains unaffected.

Categories

Resources