I'm building reusable function, but I can't change global variables values.
var foo = 5;
function MyFunction(arg) {
setInterval(function(){
foo = 2 + arg;
return foo;
}) ;
}
foo = MyFunction(1);
alert( foo );
After function complete I'm getting undefined;
Thanks in advance.
var foo = 5;
function MyFunction(arg) {
foo = 2 + arg;
}
MyFunction(1);
alert( foo );
You assigned the result of MyFunction invocation to foo and that's why you got undefined. MyFunction has no return statement.
ekuusela gives the right answer as to why your (presumably simplified) example doesn't work.
There are lots of reasons why you could have problems with globals, the most common being that you are accidentally clobbering a global by using the same identifier in some other function, and forgetting to declare it locally. To this day I still get problems where I've written for (i=0;i<n;i++) without first declaring var i in that function-- which then uses a global i, and works fine until 6 months later I make the same mistake somewhere else...
As a useful tip for debugging, the expression var G = (function(){return this})() will always give you the global object, no matter where you run it, including eval'd code. You can then access the global variable foo as G.foo, evaluate ('foo' in G) to check whether such a global exists, and so on.
In order to define a global variable you can use variable name without var keyword or define the variable outside any function scope. Then you can access it by the given method :
foo = 5;
function MyFunction(arg) {
window.foo = 2 + arg;
}
MyFunction(1);
alert( window.foo );
Note: Now foo is a part of window object.
Related
I'm not really a javascript noob at all, although in my whole life I've never came across this, but am I right in assuming that javascript must assign functions before running anything or something?
In all my experience, I expected this to return 'undefined', but obviously it returns 'function'.
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = '11';
}
alert(typeof bar());
Is someone able to explain this for me?
This behaviour of JavaScript is called hoisting. There is a good explanation on the MDN (https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
In JavaScript, functions and variables are hoisted. Hoisting is JavaScript's behavior of moving declarations to the top of a scope (the global scope or the current function scope).
That means that you are able to use a function or a variable before it has been declared, or in other words: a function or variable can be declared after it has been used already.
Basically, if you declare a variable like this:
console.log(s); // s === undefined
var s = 'some string';
s declaration will be "hoisted" to the beginning of the scope (i.e. there will be no ReferenceError on the line with console.log). The variable's value will not be defined at that moment though.
The same goes with assigning an anonymous function to a variable, so:
console.log(f); // f === undefined
f(); // TypeError: f is not a function
var f = function () {}; // assigning an anonymous function as a value
f(); // ok, now it is a function ;)
The variable will be hoisted and thus visible in the entire scope, but it's value, even if it's a function, will still be undefined - hence the error if you try to execute it.
On the other hand if you declare a named function:
console.log(f); // f === function f()
f(); // we can already run it
function f() {}; // named function declaration
It's definition will also be hoisted so you can run it even in the first line of the scope you've declared it.
This is quite easily tested;
foo(1);
function foo(i) {
if (bar()) {
alert("foo called, bar true, i = " + i);
};
}
foo(2);
function bar() {
return true;
}
foo(3);
DEMO
This shows that Javascript loads all functions before executing anything. Therefor it does not matter what order functions are defined.
Well in JavaScript function is nothing but Object.
When you say typeof bar(),in the bar function you are returning foo which is another function.You just returning name of the function,So,it return the constructor of the foo function.So,your typeof get the value of foo constructor which is type of function.So,it alert function.It still refer the foo because of closure
Again in the bar defination,you returning foo,but its definition is still not encountered.In JavaScript when while parsing the instruction,declaration of variable and function is placed on top in current function scope.
So,
your statement
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = '11';
}
is equivalent to
function bar() {
function foo() {}
return foo;
foo = 10;
var foo = '11';
This is called JavaScript top hoist
}
I was just reading the book, "You don't know JS" by kyle simpson and came across the following sinppet of code that somewhat confused me. basically I was reading a topic on the this keyword. below is the snippet:
function foo() {
console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2
So far reading the book I do understand how this works, but for me its hard to understand whats really happening on the last line of the snippet.
if I analysis it bymyself the last line is an iffe executing in the global scope and if in the iffe the foo() fuction executes, the this.a in the foo() function will point to the a in the global scope, which is indeed 2.
But somehow I don't feel i totally understand whats happening on the last line, can somebody break it down for me?
Thank you.
Alexander.
The final line is passing along the reference to the foo function and then executing in the global scope, just as you see. It is equivalent to this
var f = p.foo = o.foo;
f();
The return value of an assignment is always the value itself. At this example the return value is a reference to the function foo. Therefore two steps are executed on one line.
p.foo = o.foo;
foo();
This is whats happening:
when (p.foo = o.foo)(); is called, JS transforms it into
function foo() {
console.log( this.a );
}
and since var a = 2 is set in the global scope, and nothing is passed to the function, your result is 2
So then the question is why does JS transform (p.foo = o.foo) into the foo() function?
well if you break it down, you have this:
p.foo = o.foo : this is assigning the variable from right to left. Just like var a = "something"; so this means that now, p.foo equals o.foo, and since o.foo equals foo, we are now saying p.foo = foo, in other words this:
(p.foo = o.foo)(); is the same as (foo)() which then runs the foo function.
To further explain:
console.log(p.foo); //returns undefined because nothing was set to it
console.log(o.foo); //returns foo, because it was assigned var o = {foo: foo};
p.foo = o.foo; // this assignes foo to p.foo
console.log(p.foo); //returns foo, it is no longer undefined, because of our assignment
(p.foo)(); // will run the function
I had problems with getting undefined before, but that was because I was running tests on http://jsfiddle.net/ which prevented me from accessing my function correctly.
I came across a interesting quiz
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = '11';
}
alert(typeof bar());
My interpretation is like this (Which is wrong according to console :) ):
var foo; // global variable
function bar(){
function foo(){}
var foo; // Here variable foo should override foo function
return foo; // (according to me foo should be variable with undefined value) What is going on here, How JavaScript resolve naming order ?
foo = 10;
foo = "11";
}
Here is a reference which I am reading this
In JavaScript, a name enters a scope in one of four basic ways:
1.Language-defined: All scopes are, by default, given the names this and arguments.
2. Formal parameters: Functions can have named formal parameters, which are scoped to the body of that function.
3. Function declarations: These are of the form function foo() {}.
4. Variable declarations: These take the form var foo;
He later quoted :
The most important special case to keep in mind is name resolution order. Remember that there are four ways for names to enter a given scope. The order I listed them above is the order they are resolved in. In general, if a name has already been defined, it is never overridden by another property of the same name. This means that a function declaration takes priority over a variable declaration. This does not mean that an assignment to that name will not work, just that the declaration portion will be ignored.
Which is confusing for me, Can anyone simplify this with reference to above example ?
Main point I want to know :
How variables without var inside a function hoisted ?
Does variable overriding occurs during hoisting ?
Lets leave the function foo for the moment. Within a function, if a variable is declared anywhere inside that function, the declaration will be moved to the top of the function. So, it is actually evaluated like this
function bar() {
var foo;
return foo;
foo = 10;
foo = '11';
}
But when you have a function declared by the same name, it will take precedence and it will be evaluated similar to this
function bar() {
var foo = function() {};
return foo;
foo = 10;
foo = '11';
}
That is why you are getting function in the alert box.
Any variable without var inside a function becomes a global variable by default.
when you have a function declaration inside another function(like in your example), it gets hoisted first followed by the variable declarations.
examples to demonstrate variable overriding.
function bar() {
var foo = 10;
function foo() {}
return foo;
}
bar(); //--> returns 10;
function bar() {
var foo;
function foo() {}
return foo;
}
bar(); //--> returns the function object foo.
Consider two styles of javascript function declarations (out of four, I think):
function foo() {
// ...
}
versus
var foo = function() {
// ...
}
In many circumstances these will behave the same, and I think I grok the main difference as explained in e.g. these SO questions:
difference-between-var-foo-function-and-function-foo
usual-functions-vs-function-variables-in-javascript
which both have answers linking to this very helpful explanation:
javascript-function-declaration-ambiguity
But I would like to combine both styles in one statement; one short/minifiable local variable name (because I will need to refer to it quite often) and one descriptive name (I want to get something friendly out of .name).
This is where I get confused. It is as if the act of immediately assigning the function to a variable leaves it undefined under its own name:
var f = function foo() {
// ...
};
console.log( f.name ); // "foo"
console.log( foo.name ); // !? error: foo is not defined ?!
So to get to the question: why does this not work? Or, more likely, what might I still be misunderstanding about these two declaration styles?
Note, that the following does not result in an error:
var f = foo;
function foo() {
// ...
}
console.log( f.name ); // "foo"
console.log( foo.name ); // "foo"
How, exactly, is this different?
PS: I think this is different from this SO question:
in-javascript-what-is-the-motivation-or-advantage-of-using-var-foo-function-f...
which is about a special case of my predicament, where the variable name and function name are the same, i.e.
var foo = function foo() {
// ...
};
When you write
var f = function foo () { ... }
the scope of foo is just the body of the function, not the enclosing function. This is mainly useful for creating anonymous recursive functions.
whats the difference between function foo(){} and foo = function(){}?
recommends against using that notation, because they don't work correctly in some implementations.
This is how I see it. Every function in javascript inherits from Function object and Function object has property .name.
this creates the function object with the name foo in the global space:
function foo(){}
this creates local anonymous(thus no name) function and assigns is to the variable f which lives in global space:
var f = function(){}
this creates the function object and assigns it to variable, it doesn't exist in global context, only local to f, the same as above, but assigns the name foo:
var f = function foo(){}
edit: for better picture consider following
(function foo(){console.log("executing foo")})();
(function(){console.log("executing anonymous")})();
are both function(objects) in global context - first with name, second without name. If they are created in variable it works the same just context is different.
I'm trying to learn JS on codeacademy and I can't understand/get past this thing. Can someone please provide an answer and also an explanation of why is it so? Would deeply appreciate.
// This function tries to set foo to be the
// value specified.
function setFoo(val) {
// foo is declared in a function. It is not
// accessible outside of the function.
var foo = val;
}
setFoo(10);
// Now that we are outside the function, foo is
// not defined and the program will crash! Fix this
// by moving the declaration of foo outside of the
// function. Make sure that setFoo will still update
// the value of foo.
alert(foo);
You can see scope as a term meaning what variables you can reach at a specific "level" in the code. In JavaScript, these "levels" are defined by functions. Each function introduces a new level.
For example, take this sample code:
var a;
// you can access a at this level
function function1() {
var b;
// you can access a, b at this level
function function2() {
var c;
// you can access a, b, c at this level
}
}
So in your case, you should declare var foo; outside the function, preferably above it. Then you can set it inside setFoo with foo = val;. foo then refers to the one you declared in the level above setFoo.
foo is accessible both in setFoo and in the alert call that way; compare it with the above sample code (function1 is setFoo, a is foo and the alert call is in the top-most level. function2, b and c are not used in your case.).
// Create globale variable
// (You should not use globale variables!)
var foo;
// set value
function setFoo(val) {
foo = val;
}
setFoo(10);
// show value
alert(foo);
Just declare foo outside any function then it will be global:
var foo = null;
function setFoo(val) {
foo = val;
}
setFoo(10);
alert(foo);
Try it !
When you declare a variable in Javascript it is only visible to code that is in the same function as it is declared, or a function inernal to that function. Because foo is originally declared in the SetFoo function nothing outside of SetFoo is able to see it, so the call to alert fails as foo does not exist in the gloabl scope.
As the comments suggest, moving the declaration of foo out of the function and into the global scope (which you can think of as a catch-all function that contains everything) would allow you to use foo when calling alert.
var foo;
function setFoo(val) {
foo = val;
}
setFoo(10);
alert(foo); // No longer crashes
Every function in Javascript has it's own scope. That means that every variable you define there with the var keyword, will only be available within that function. That means that when you call setFoo(10), you create the variable foo, give it a value of five, after which it is immediately destroyed because it went out of scope.
There are multiple ways to solve this problem. The first would be to remove the var keyword. This would put foo in the global scope, which means that it's available everywhere. However, this is discouraged, you want to keep the global scope as uncluttered as possible, so that if you have javascript code provided by multiple people on the same page, they can't overwrite other people's variables. Another way to do it would be this:
function setFoo(val){
var foo = val;
alertfoo = function(){
alert(foo)
}
}
In this example, the only thing you're putting in the global scope is the alertfoo function, because you want that to be available everywhere. The alertfoo function is defined inside the setFoo function, this means that although foo should have gone out of scope after setfoo has been executed, it is kept in memory, because alertfoo has access to it.
This makes for some nice tricks. For example, let's say you're making a javascript library that will be included on other people's pages, you'll want to create a scope inside of which you can define variables, without polluting the global scope. The most common way to do this, is by declairing a self-executing function. This is a function which is executed immediately after being defined, it looks like this:
(function(){
//set variables you want to be global in your own code
var mainpage = document.getElementById('main');
//define functions you want to make available to other people in a way that puts them in the global scope
setMainElement = function(newmain){mainpage = newmain;}
})();
You can make this even better by making only one object global, and provide your interfae through the methods of that object, this way, you create a namespace with all the functions that your library contains. The next example uses an object literal to do this. In javascript, you can create an object by putting key/value pairs petween curly braces. the key/value pairs are properties of the object. for example:
(function(){
var privatevar = 10,otherprivate=20;
publicInterface = {
'addToPrivate': function(x){privatevar+=x;},
'getPrivate': function(){return private}
};
})();
Original code:
function setFoo(val) {
var foo = val;
}
setFoo(10);
alert(foo); // Crash!
Their advice to fix the crash:
Fix this by moving the declaration of foo outside of the function
I'm guessing you're confused as to what they mean by "outside of the function".
Try this edited code:
var foo = 5; // "var" declares the variable to be in this outer scope
function setFoo(val) {
foo = val; // but we can still access it in this inner scope...
}
setFoo(10);
alert(foo); // Displays a dialog box that says "10"
Variables defined in the function is valid only in the function
function setFoo(val) {
foo = val;
}
In JavaScript, new scopes are only created by functions