Why can't I access variables inside a function? - javascript

If functions are objects in javascript, why can't I access the function scope defined variables?
I understand that in the code:
// variable test assigned an anonymous function
var test = function(){
var x = 5;
};
console.log(test.x); // undefined
// Even when the function is explicitly named:
function test(){
var x = 5;
}
console.log(test.x); // undefined
I don't need to get this working or anything; I just need to understand why functions are like this.
Thanks.

This would be one way to accomplish what you are trying:
function test() {
this.x = 5;
}
var foo = new test();
console.log(foo.x);
Using var x rather than this.x just declares a local variable

I believe it is because those variables only exist within the scope of the function you have defined. Outside the scope of that function they do not exist.
They are the equivalent of private members in a class of an object oriented language.
Alternatively you could have
function test() {
this.x = 5;
}
var testInstance = new test();
console.log(test.x);

Functions are objects, but that doesn't mean that any variable declared inside the function becomes a property of that function object. In fact, that would be terrible because you wouldn't be able to run a function more than once (since the second time, the variables would start with different values).
You can assign a property to a function object like this:
var test = function () {};
test.x = 5

The variable is visible only in the function and it is possible to access it only within the function, you can use global variable and then edot it insode the function.

You have created Local variables. Local variable can only be accessed within the function.
Try to understand about Local & Global JavaScript Variables
Local JavaScript Variables
Variables declared within a JavaScript function, become LOCAL to the function.
Local variables have local scope: They can only be accessed within the function.
function myFunction() {
var name = "roy";
// code here can use name
}
Global JavaScript Variables
A variable declared outside a function, becomes GLOBAL.
A global variable has global scope: All scripts and functions on a web page can access it.
var name = "roy";
// code here can use name
function myFunction() {
// code here can use name
}

var someName = function(){var x ...} /// only has local scope.
What is the scope of variables in JavaScript?
Will describe it better than I can. Good job on being curious and motivated.

Related

Not understanding the concept of local and global variables

Ok so just a quick one... I REAAAAAALLLLY am not understanding scope at all. Do some reason whenever I put a variable inside of a function it's undefined. It seems the only way it works it to declare it OUTSIDE of a function. So what gives? Am I simply misunderstanding the concept of local and global variables? Because it seems global variables are the only ones that work...
Edit:
Simple example...
let a = 'something';
function myFunction() {
// Code block
};
This works 👆
But the following gives me undefined variables:
function myFunction() {
let a = 'something';
// Code block
};
First lets take a look at the differences between local and global variables.
LOCAL VARIABLES - Any variable defined inside of a function or loop. If the variable is defined in a certain function/loop, it can only be accessed in that function/loop.
For example:
function number() {
let a = 0;
// Can access a here.
}
// Cannot access a here.
GLOBAL VARIABLES - Any variable that is not defined inside of any function or loop. These variables can be accessed anywhere.
For example:
let b = 0;
function number() {
// b can be accessed here.
}
// b can be accessed here.
The scope of a variable is where it can be accessed in. For ex, a scope of a local variable that is defined inside of function number() is the number() function since it can only be accessed there.
One more quick thing (Credit to Mikael Lennholm) var doesn't scope a variable to a loop (or any non-function statement block), it only scopes it to the current function. To scope a variable to any statement block you have to use let/const
Now let's look at your examples:
Here is the first example:
let a = 'something';
myFunction();
function myFunction() {
console.log(a);
};
That works fine, and that's what you said.
Here is the second example you said doesn't work:
function myFunction() {
let a = 'something';
console.log(a);
};
myFunction();
But, if you click the run button, you'll actually see it does work, it does get logged. If you after this go and check in the console what the variable a is of course it will be undefined, since a can be only accessed in the myFunction() function, and the console is not in that function.
You said that the script doesn't work, it's most probably because of something else (if it was because of this there would be an error in the console). You can try posting the website here and I can help you.
Hope this helped you :)
Global variables are variables that you have access to them anywhere in your codes.
Local variables are limited to their scopes like a function, module, class and etc.
if you define a local variable it can be accessible in the nested level like closures.
if you define a global variable and you define the same name as local variable , the local overwrite the global, then be careful.

How should I access to overwritten variable in overwritten function?

I'm not able to understand of how should I get to particular variable a in next code:
var a = 1;
console.log(a);
function local() {
var a = 2;
console.log(a);
function local() {
var a = 3;
console.log(a);
function local() {
var a = 4;
console.log(a)
}
local();
}
local();
}
local();
I know this is artificial example but I can't go to sleep without the answer :)
So how should I get a particular variable a from any of overwritten function?
Thanks.
When you declare a variable in the local scope with the same name as a variable in a higher scope, the new declaration hides the higher scoped variable and there is NO way to access that higher scoped variable from the local scope.
This is just how Javascript is designed. There isn't some magic way around it. If you want access to the higher scoped variable, then don't declare a local variable with the same name. Pick a different name.
If the top-most variable is in the global scope, then you might be able to access that variable with a global prefix such as window.a or global.a (depending upon which environment you're running in). But, the intermediate variables that are not in the global scope are not accessible.
you can access global variables by the window object like this
var aa=11;
function my_func(){
var aa=22;
alert("local: "+aa+" global: "+window.aa);
}
but there is no way of accessing the local variables outside the function, as they do not really exist out there!

Javascript Global vs Local Scope

I'm currently trying to understand Javascript's interesting take on global vs local scope.
My question is that why would the following returns undefined?
var a = 100;
function local() {
if (false) {
var a = 50;
}
alert(a);
}
Additionally, I ran this:
var a = 100;
function local() {
alert(a);
}
The result was a resounding: 100.
Is there some way that we can specify when we want the variable to be taken from the global scope, like a PHP global keyword, that we can use with Javascript?
Because of hoisting.
It means every variable declaration get's popped to the top of the function so the actual code that runs is:
var a = 100;
function local(){
var a;
if (false)
a = 50;
alert(a);
}
It has very little to do with global VS. local, you simply hid the outer a variable with the inner a variable.
Is there some way that we can specify when we want the variable to be taken from the global scope, like a PHP global keyword, that we can use with Javascript?
No
Regarding the question in the comment "In the case that I want to revert to using a global variable in case the if condition fails (which I intentionally did), how can I do so? ":
You can use eval:
var a = 100;
function local() {
if (false) {
eval('var a = 50;');
}
alert(a);
}
Live DEMO
But you should not!
JavaScript has function scope, not block scope (as many other programming languages). That means regardless where the var statement occurs (in your case, an if-branch that is not even executed), it declares a variable a in the function's local scope. It shadows the global a variable, but since it has no value assigned it returns undefined.
Is there some way that we can specify when we want the variable to be taken from the global scope, like a PHP global keyword, that we can use with Javascript?
You can access the variable as a property of the global object (window in browser environments):
var a = 100; // global
function loc() {
var a = 50;
alert(window.a); // 100
alert(a); // 50
}
loc();
However, you will hardly use this. Global variables are to be avoided in general, and in case of name clashes you should simply rename your local variable (for readability and maintainability at least).
I know that if a variable is in defined inside a function using var, then it will have Local Scope.
I also know that any function has easy access to Global variable.
When I tested following in Console of Browser, first output was undefined.
It means that function nwf() was unable to access Global variable nw1
This is due to reference error which highlights importance of Strict Mode
To avoid such scenario, never re-declare and/or initialize any variable with same name inside and outside any function, just unlike following:-
var nw1 = 1; // var creates global scope outside function
function nwf() {
alert(nw1);
var nw1 = 2; // var creates LOCAL scope inside function
alert(nw1);
};
nwf();

how can global function expression can access variable inside containing function in javascript

Here is an example:
function outerFunc(){
//some variable
var x = 10;
Obj = function(){ //Its global function created without var keyword
this.a = x;
}
}
So now when I create new instance of Obj object after calling the outerFunc function.
outerFunc();
myObj = new Obj();
myObj.a; //prints 10
So I wonder how can it read containing functions private variable x when I define Obj as global constructor, it still can read the value.
You can't access the property x declared in the closure from outside.
Here, you don't read the value of the private variable x, but the copy you made and stored into
a.
If your question is why you could access x from inside the function Obj : that's simply how closures work : a function can access the variables of the scope in which it was declared. The fact that this function is assigned to the Obj variable and that this variable is global changes absolutely nothing.
Here's some additional reading : the MDN on closures

Trying to figure out how scope works

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

Categories

Resources