In the following example
var foo = "bar;
(function () {
var hello = "world";
debugger;
}());
the variable foo is declared in the global scope, thus it becomes a property of window and the expression window.foo returns "bar".
If I stop at the breakpoint in the iife and type hello in the terminal, it returns world.
But on which object is the variable hello stored in?
It will have local scope limited to that anonymous function
unless specified it will not associated with any object.In your code it exists independently as hello itself and will not be accessible out side that function
var foo = "bar;
(function () {
var hello = "world";
debugger;
}());
If you want it to be associated with any object you could do it as
var foo = "bar";
var obj={};
(function () {
obj.hello="world";
console.log(obj.hello);
})()
console.log(obj.hello);
Hope this helps
Global scope variables are a syntactic sugar of adding a property to the global object window or global in NodeJS: var a = 11; is the same as window.a = 11;.
How local variables are stored in memory is a concrete JavaScript runtime implementation detail. I wouldn't mind about how's stored since it has no interest in a high level language like JavaScript. They're just variables like in any other old or modern programming language.
Maybe you'll find this other Q&A a good resource to learn more about JavaScript scoping: What is the scope of variables in JavaScript?
Related
I am working on a javascript file with javascript functions that are not inside a closure. Obviously the function is callable by the console.
I know that adding a closure is best practice. But while tinkering i found that if I add in my file
window.myFunction = {}
the function becomes unavailable through the console.
Is this safe ?
All global variables/functions in Javascript (Browser) are a property of the window object:
var x = "foo";
console.log(window.x); //foo
It's not best practice to pollute the global scope, but it isn't "unsafe" if you control which scripts your page uses. (Although I don't recommend using global variables)
If you do need to have a global variable, consider using a name that you know other script won't use:
(function(window, undefined){
var privateVar = 5;
window.mySite = {
foo: "bar",
func: function(){
return "foo";
}
};
})(window);
console.log(window.mySite.func()); //"foo"
console.log(privateVar) //undefined
Now outside of the IIFE (Immediately-Invoked Function Expression) you can use window.mySite or just mySite, while privateVar won't be accessible.
More info on the window object here
JavaScript normally follows the function scope i.e. variables are accessible only within the function in which they are declared.
One of the ways to break this convention and make the variable accessible outside the function scope is to use the global window object
e.g.
window.myVar = 123;
My question is are there any other ways in JavaScript/jQuery to make the variable accessible outside the function scope?
Not with variable declarations, no. You can obviously declare a variable in an outer scope so that it's accessible to all descendant scopes:
var a; // Available globally
function example() {
a = "hello"; // References a in outer scope
}
If you're not in strict mode you can simply remove the var keyword. This is equivalent to your example:
// a has not been declared in an ancestor scope
function example() {
a = "hello"; // a is now a property of the global object
}
But this is very bad practice. It will throw a reference error if the function runs in strict mode:
function example() {
"use strict";
a = "hello"; // ReferenceError: a is not defined
}
As you wrote, variables are only visible inside the function in which they were defined (unless they are global).
What you can do is assign variables to the function object itself:
function foo() {
foo.myVar = 42;
}
console.log(foo.myVar); // outputs "undefined"
foo();
console.log(foo.myVar); // outputs "42"
But I would advise against it. You should really have a very good reason to do something like this.
You can define them as part of a global object, then add variables later
// Define your global object
var myObj = {};
// Add property (variable) to it
myObj.myVar = 'Hello world';
// Add method to it
myObj.myFunctions = function() {
// Do cool stuff
};
See the link below:
Variable declaration
Also, you can declare it without the var keyword. However, this may not be a good practice as it pollutes the global namespace. (Make sure strict mode is not on).
Edit:
I didn't see the other comments before posting. #JamesAllardice answer is also good.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What advantages does using (function(window, document, undefined) { … })(window, document) confer?
I'm increasingly seeing code like this in libraries I've been using:
(function (window) {
var Foo = function () {
}
window.Foo = Foo;
})(window);
The argument I've seen for doing this is to avoid working in the global scope when creating (pseudo) classes. But, correct me if I'm wrong, I always understood that window IS the global scope. I believe, when you create a global variable, you are really only adding a property to window anyway... Unless this is changing for ES5 strict?
So, basically, what's the point? The only benefit I can see to code organised like this is if you wanted to easily change the namespace of your classes at a later date by passing in an argument other than window.
Infact, strict mode throws an exception if you forget to use var for any variable declaration. But that works even without using an outer closure.
Using this pattern is much more for protecting yourself from the outside javascript world. For instance, some other script overwrites window.undefined or any other variable, you can grab the value within that closure to savely access it from within.
For instance
(function _myApp( win, doc, undef ) {
// app code
}( this, this.document ));
Also, when declaring variables with var, or creating function declarations, those are always stored within the current Activation Object respectively the Lexical Environment Record. That means, without using a Function context, you can easily overwrite methods and variables from some other point, because all of those would get stored in the current Context (which would be the global one)
So:
(function _myApp( win, doc, undef ) {
var myVar = 42;
function myFunc() {
}
}( this, this.document ));
(function _myModule( win, doc, undef ) {
var myVar = 42;
function myFunc() {
}
}( this, this.document ));
This works because of closure and Context, but if you would use the same code, without the Function Context, we would obviously overwrite our myVar and myFunc. This could happen from everywhere, within the same file or in another loaded script.
As evil as global variables are, you need to have atleast one or there's no way to access your script. The code you provided is one way to create that one global variable. I prefer this way:
window.Foo = (function () {
var func = function () {
// ...
};
return {
func: func
};
})();
Your're right, but the difference is that the code inside of the function acts like an automatic init function.
(function (window) {
var Foo = function () {
}
var Bar = 69; // not in global scope
window.Foo = Foo; // in global scope
})(window);
As opposed to
var Foo = function () { // in global scope
}
var Bar = 69; // in global scope
and
var Foo = function () { // in global scope
}
function init () {
var Bar = 69; // not in global scope
}
init();
Javascript closure definition says :
A "closure" is an expression (typically a function) that can have free
variables together with an environment that binds those variables
(that "closes" the expression).
Can some one explain to me the concept of free variables ? Is this concept Javascript specific or applies to other languages also ?
Free variables are simply the variables that are neither locally declared nor passed as parameter.
Source :
In computer programming, the term free variable refers to variables
used in a function that are not local variables nor parameters of that
function.1 The term non-local variable is often a synonym in this
context.
In javascript closures, those are simply the variables that the function takes (read and write) in the enclosing scope where is declared the closure or in a parent scope.
Look at this real world example :
Gol.prototype._ensureInit = function() {
...
var _this = this;
var setDim = function() {
_this.w = _this.canvas.clientWidth;
_this.h = _this.canvas.clientHeight;
_this.canvas.width = _this.w;
_this.canvas.height = _this.h;
_this.dimChanged = true;
_this.draw();
};
setDim();
window.addEventListener('resize', setDim);
...
};
In this example a closure points from the setDim function towards the variable _this declared in the enclosing scope (the _ensureInit function). This variable isn't declared in setDim nor passed. It's a "free variable".
Note that _this doesn't become a variable of the function setDim : another function declared in the same scope would share the same variable.
A "free-translation" could be: "out of scope" - variables.
Since ECMAscript uses lexical scoping, a free variable is a variable which was defined in a parent-scope and gets looked-up by a scope-chain search.
(function _outerScope() {
var foo = 42;
(function _innerScope() {
var bar = 100;
console.log( foo + bar ); // 142
}());
}());
In the above example, foo is a free variable within the context of _innerScope. it becomes very obvious if we have a quick glance into the underlying concepts of ECMAscript.
A Context is linked to an Activation Object (in ES3), respectively a Lexical Enviroment Record (in ES5), which contains things like: function declarations, variables declared with var and formal paramters, as well as a reference to all parent Activation Objects / Lexical Environments. If a variable needs to be accessed, the ECMAscript engine will first look into the AOs / LEs from the current Context itself; if it can't be found there, it looks into the parent AO's / LE's.
Since any Context stores this data in an array-like structure (don't forget we're talking about implementation level here, not Javascript itself), we are talking about Lexical Scope, because we search through all parent Contexts in order.
As an example:
var myModule = (function (){
var moduleVar; // closure variable
return function(){
// actual function
}
})();
the variable defined there is a closure variable. it can be used all over the closure itself but is not part of a global namespace.
I don't remember how many times I've read JS books and revise some topic in which the closure topic is there.
The answer is just an addition to the accepted answer.
The following example is excerpted from Modern JavaScript for the Impatient,
Cay Horstmann
// text is a free variable of the arrow function.
const sayLater = (text, when) => {
// vv
let task = () => console.log(text) // (heed no 'text' variable here) => console.log(text)
setTimeout(task, when)
}
Now you can grasp the meaning of
The term free variable refers to variables used in a function that are
not local variables nor parameters of that function.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Confused by Javascript's variable scope
For example, this is my JavaScript code:
var foo = 'Originalvalue';
var foo = 'Nextvalue';
alert(foo); // Nextvalue
So then, now I am sure writing var in front of an already-declared variable just simply is nullified and of no use to the program.
But then consider this program:
var foo = 'Originalvalue';
function duhfoo() {
var foo = 'Newbievalue';
}
duhfoo();
alert(foo); // Originalvalue
Then, from the logic explained in my first example, the value should be 'Originalvalue', as there is already a variable called foo. Then why is it like so?
In Javascript there are two kinds of variables: local variables and global variables.
When using var outside of functions you are declaring a global variable and the same happens if you don't use var at all. Writing
foo = "first";
at top level (outside any function) is the same as var foo = "first".
When inside a function however things are different, and the keyword var discriminates between local and global variables:
var foo = "first";
var bar = "second";
function f()
{
var foo = "third"; // local
bar = "fourth"; // global
}
f();
alert([foo, bar]); // output will be first,fourth
In other words when you use var inside a function the variable will be a different one with the same name, visible only by code written inside the boundaries of the function.
Please note that the boundary is determined by the function, and not the braces {...}. If you have nested blocks and use another var declaration inside the blocks the variable will be the same and this is different from what happens in other languages like Java, C or C++.
The only way to create a scope is to define a function (including a function inside a function).
Another very important thing to remember in Javascript (especially if having been exposed to similar-looking languages in which this concept is not present like Java, C or C++) is the idea of "capture"/"closure"...
var foo = "first";
function f()
{
// Local variable
var foo = "second";
function g()
{
// This is the local foo of f, not the global
// one even if there is no "var" declaration
// inside this nested scope
return foo;
}
return g;
}
var nested_function = f();
alert([foo, nested_function()]); // output will be first,second
Basically a local variable can "outlive" the function that defined it, by being used by other functions that are said to "capture" that variable. A function that captures one or more variable is called "closure".
In other words a local variable is only visible inside the body of the function, but it may live longer than then function like it happens for the local foo of last example in which the variable survived after returning from f because it has been captured by closure g.
well variable foo inside duhfoo clearly states that its scope is duhfoo() method and not global.
Because
(From MDN)
var has the following properties
function-scoped
hoist to the top of its function
redeclarations of the same name in the same scope are no-ops
Please read this for more information on this subject.