Why does console log show variable that is already defined - javascript

Curios why this happens
if(typeof TEST === "undefined") {
var TEST = true;
console.log(TEST);
}
if i place in console , it returns true
if i add again in console , then no console log is shown , which is exactly how I would assume it should work.
When i place in interval , why does it continue to log the variable even though its defined ?
setInterval(function(){
if(typeof TEST === "undefined") {
var TEST = true;
console.log(TEST);
}
}, 1000);
How can you make it stop showing the log after its defined ? Without clearing the interval

If you put it in the console then var creates a variable in the top level scope. It is undefined, so you assign true to it. If you put it in the console again then it is true from the previous time.
If you put it inside a function, then it is scoped to the function, so every time you run the function you create a new scope and a new var TEST.
Declare the variable in a scope outside the function instead.

In the first case, you're testing the global variable. Once it's defined, it stays defined.
In the second case, the variable is local to the callback function. Every time the function is called, it's a new variable that isn't defined yet.
If you remove the var declaration in the setInterval() version it will assign to the global variable, and it will stay defined.

The simplest solution is probably to use let or const instead of var. If of course you have the possibility.

Related

Javascript - changing a global variable in document.ready?

I have a global variable numberOfMessages that I want to immediately set to a particular number according to what a call to a solidity contract brings back. The call is made in the document.ready function when the page is loaded. However, the variable isn't changed outside this function.
My code is basically like this:
var numberOfMessages = 0 // declared outside any function, so should be global
$(document).ready(function () {
Message.deployed().then(function (contractInstance) {
contractInstance.getNumberMessages.call().then(function (v) {
numberOfMessages = v
alert(numberOfMessages) // returns something other than 0
})
})
})
alert(numberOfMessages) // returns 0
How can I have a global variable that is set to what a function returns when the page is loaded?
Your final line is running outside of the promises' .then() async callback. This means the last line runs before document ready even fires and before your async call finishes.
Also, don't use alert() to test your code since prompts like that are usually blocking, meaning the halt code execution and can do weird things with async callbacks. Instead use console.log() and see the results in your browser's Javascript console (usually opened by hitting F12).
Try to remove
var numberOfMessages = 0
at first line. If you assign a value to a variable that has not been declared, it will automatically become a GLOBAL variable.
According to several other similar questions I could say declare your variable as window.numberOfMessages = 0.
#3 window.a = 0;
This creates a property on the global object explicitly, using the
window global that refers to the global object (on browsers; some
non-browser environments have an equivalent global variable, such as
global on NodeJS). As it's a normal property, you can delete it.
This property is enumerable, on IE8 and earlier, and on every other
browser I've tried.
Above classification has posted by here and gives you an explanation of what is a global scope variable and global explicitly variable.
window.numberOfMessages = 0 // This creates a property on the global object explicitly
$(document).ready(function() {
Message.deployed().then(function(contractInstance) {
contractInstance.getNumberMessages.call().then(function(v) {
window.numberOfMessages= v
console.log(window.numberOfMessages) // returns something other than 0
})
})
})
console.log(window.numberOfMessages) // returns 0
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Function that uses a variable defined with let on function execution

I'm wondering why I'm getting an error of "x variable not defined" inside a function that uses a variable that is declared on the same line that I execute the function. Here is the snippet (ES6)
let timeout = resetTimeout();
function resetTimeout () { timeout = 0; return timeout }
why is the scoping acting here? the variable is being defined BEFORE the function definition, so, why?
EDIT
To clarify the question, I know that it will work with var. I already read about the scoping of let and const, and I'm unable to understand why this does not works as I expect. What I'm looking for is for an explanation, not a solution.
You are creating a variable using let and immediately assigning a function's return value to it. This is okay.
The problem is inside the function. Without specifying the type of the variable timeout (= 0) you are dealing with the same timeout defined using let before. So there is a circular reference. Let's see how your code executed :
1 - First line calls the function, timeout is created in the scope but it's value undefined yet.
2 - In the function body the 'timeout' is tried to be set to 0. Since it is in the scope, js cannot create a global variable (which normally does) and assignment will throw an error.
Fix? If you intended the timeout inside the function block to be local, just rename it.
Using let is just fine.
The key concept here is "hoisting."
Every variable declared with 'var' is first hoisted, then it will be assigned; With 'let' it is different, it will not hoist the variable, so first js will evaluale the right side of the assigment; at that point the variable is not defined yet!
The next, slightly different code works with let:
let timeout
timeout = resetTimeout()
function resetTimeout () { timeout = 0; return timeout }
Note: A variable declared by let or const has a so-called temporal dead zone (TDZ) (see http://2ality.com/2015/02/es6-scoping.html#the_global_object)
Taking into consideration your update and this guy's answer, I would like to state that you don't need to rename your variable. Since let works only on one layer and do not go deeper into scope, you can declare new variable timeout within the function.
let timeout = resetTimeout();
function resetTimeout () { let timeout = 0; return timeout; }
Hope that helped a bit. Sorry for previous answer.

Get variable value of a function without setting it globally

Is it possible to get a variable value inside a function without having to set it globally?
I know this is possible:
var testvalue;
function setTestValue(){
testvalue = 30;
}
if you console.log this outside the setTestValue function you will get: 30. Which is clear.
But is there also a possibility to have the same effect but without a global variable?
function setTestValue(){
var testvalue = 30;
}
console.log(testvalue); // will print undefined
The reason why I want this is because I can not change the Javascript file where this function is created. I can only read it and not write it so I need it a workaround.
PS. It might be that this question is already been aksed on stackoverflow but I could not really find it. So if there is, please provide the links to that question.Thanks!
This works (if you don't have var keyword before the variable in the function )
function foo() {
bar = 10; // variable without var comes under window scope so you can access them outside fuction
}
foo();// you have to call the function to set its value
alert(bar) // window.bar also gives 10
why not returning the var in the function:
function setTestValue(){
var testvalue;
do whatever to assign value
return testvalue;
}
console.log(setTestValue());

function(a){ var a='test'; } : Is "var" required? What if a is undefined?

Quite a javascript 101 question, but, here goes:
function test(a){
var a='test';
}
Is the "var" required to keep the variable from going global?
function test(a){
a='test';
}
Would this suffice?
How about if the function is called with a undefined?
function test(a){
a='test';
}
test();
In the above snippet, would a become global?
Every parameter is implicitly a var.
(The argument value supplied doesn't matter.)
You can pass arguments to a function. These are considered local variables inside the functions scope regardless of wether the function is called with those arguments or not.
If the function is called without supplying a value for all the arguments, the arguments that are not passed when calling the function are set to a value of undefined, but they are still declared inside the functions scope as locals.
function test(a){
var a = 'test';
}
Is the "var" required to keep the variable from going global?
No the var keyword is not required, and in fact should not be used, as you're redeclaring the a variable, and redeclaring variables is not allowed.
function test(a){
a = 'test';
}
Would this suffice?
Yes, that's fine and is the way it should be done. You alread have a variable named a, and now you're setting it to a different value.
How about if the function is called with a undefined?
function test(a){
a = 'test';
}
test();
As mentioned above, it doesn't matter, the argument a is still declared as a local variable inside the function, the value is just set to undefined, so the var keyword should not be used as you're not creating a new variable, a already exists, you're just giving it a new value.
If you are not using "use strict" then if you don't use var, a will be attached to the global namespace implicitly, which in a browser is equivalent to window.a. This is known as "polluting the global namespace" and is generally considered bad practice.
This is not the same as a formal argument bound to a name, as is in your examples. This lives in the function scope as 'a'
However, if you use "use strict", the absence of var throws an error in environments that support "use strict" for any variables not formally bound in the function signature. It basically safeguards against bad practices and potential mistakes/bugs in your code that are easy to make
Edit:
I actually think its worth mentioning let too, which is a way of explicitly binding a variable for use in a given scope. So you needn't use var, if you use let
Check support for this keyword in your environment first!
Well, there are some points to comment:
First of all, within a function variables must have var if they are not a reference to an outside var:
var outside_var = "OUT!";
var myFunction = function() {
var inner_var = "IN";
console.log(outside_var); //Will prompt "OUT!"
console.log(inner_var); //Will prompt "IN"
}
console.log(outside_var); //Will prompt "OUT!"
console.log(inner_var); //Will prompt undefined
Another point is that every var defined as an argument, is already defined in function scope, you don't need to declare it with var:
var outside_var = "OUT!";
var myFunction = function(a) { //imagine you call myFunction("I'M");
var inner_var = a + " IN";
console.log(outside_var); //Will prompt "OUT!"
console.log(a); //Will prompt "I'M"
console.log(inner_var); //Will prompt "I'M IN"
}
console.log(outside_var); //Will prompt "OUT!"
console.log(a); //Will prompt undefined
console.log(inner_var); //Will prompt undefined

javascript: creating a local scope of a global variable undefines it before it is set

I do not understand this behavior:
var a = 1;
console.log('a is undefined1:', a == undefined);
var a;
//iterate selected jQuery elements:
jQuery.each(this, function(index, htmlElement) {
console.log('a is undefined2:', a == undefined);
var a;
Returns:
a is undefined1: false
a is undefined2: true
If the last line (var a;) is commented out, this is returned:
a is undefined1: false
a is undefined2: false
I would expect always the latter output. What do I not know?
Thanks so much!
Putting var a inside a function creates a different a variable that is scoped to that function.
Since you don't assign a value to it, it is undefined.
When you comment it out, you are testing the outer a which has the value of 1.
Variables are hoisted. It doesn't matter where in a function you use var foo, the foo for that function still applies to the whole function.
Declaring variable within function using var makes local copy (new variable) with scope on the whole function - it does not matter whether it is used before it is declared.
Never declare variables without var.
If you want to access the golobal variable and you have local variable of the same name, you can access the global foo variable using window.foo

Categories

Resources