For some time now, I've used const to declare most variables.
If I don't absolutely know for certain that a new variable will always hold the same value, I will declare the new variable with let.
I almost never use var.
That's me.
However, any other individual writing javascript will have their own preferred variable declaration conventions and, if I am accepting user-generated-content such as User Written ES6 Modules there's no way predict with confidence what those conventions might be.
Leaving aside const for the moment...
var can be overwritten by var:
I know that the following:
var myString = 'My String declared with var';
var myFunction = function() {console.log('My Function declared with var')};
can be overwritten with identically named variables declared with var.
Example:
var myString = 'My String declared with var';
var myFunction = function() {console.log('My Function declared with var')};
var myString = 'My Overwriting String declared with var';
var myFunction = function() {console.log('My Overwriting Function declared with var')};
console.log(myString);
myFunction();
let cannot be overwritten by var:
I also know that if myString and myFunction are declared with let
let myString = 'My String declared with let';
let myFunction = function() {console.log('My Function declared with let')};
they cannot subsequently be overwritten with var, let, or const.
Example:
let myString = 'My String declared with let';
let myFunction = function() {console.log('My Function declared with let')};
var myString = 'My Overwriting String declared with var';
var myFunction = function() {console.log('My Overwriting Function declared with var')};
console.log(myString);
myFunction();
So, knowing both these things, is it a reasonable safeguard to convert any var declarations to let declarations (either at compile time or at runtime) in all User Submitted ES6 Modules?
Are there any conceivable contexts / situations in ES6 Modules where it wouldn't work to update var to let?
If a user wrote a function like this, changing var to let would fail:
function run() {
for (var i = 0; i < 3; i++) {
console.log(i);
}
console.log('final i', i);
}
console.log('starting run');
run();
function runLet() {
for (let i = 0; i < 3; i++) {
console.log(i);
}
console.log('final i', i);
}
console.log('starting runLet');
runLet();
the runLet function errors because i is undefined.
calValue: function (data) {
var self = this;
var values = data.values;
for (var i = 0; i < data.length; i++) {
if(data.condition == 0){
(function (values) {
for (i = 0; i < values.length; i++) {
}
})(values)
}
else{
//do sth else
}
}
}
my understanding is each funtion has its own context and the variable being declared inside it, will only be effetive inside. Like above code snippet, i expect the "i" variable inside the inner for-loop won't impact the outer one "i" variable. However, the fact is it do affect.
Could someone please help explain? Thanks.
With var declarations, scope is at the function level. Such declarations are interpreted as if they appeared at the very start of the enclosing function.
In modern JavaScript environments, the let declaration allows you to create variables scoped to local blocks of statements. (Also const for non-modifiable symbols.)
In your case, that inner i in the nested function just refers to that i declared externally. From inside a function, you can always "see" out, but you can't "see" in. That's how scope works.
Eval is generally disliked, but it seems necessary.
Currently, I have an ajax call that retrieves a html file that has inline javascript. Then it gets the script by tagname and evals it.
This all works fine, but what I can't figure out is where all the vars go.
For instance, in a normal case, everything can be found in window:
var you = "buddy"
alert(window["you"]);
//Alerts : "buddy"
But when I do an eval, I don't know what the equivalent of 'window' is. I'm not sure where all the vars end up.
What I would like is some way to get a list of all of them, without any of them overriding vars that exist in the global scope.
eval will share the global context (window) and any local variables. If executed in global scope:
eval('var a=1; b=2');
console.log(window.a, window.b);
// => 1 2
new Function will create a new local scope:
new Function('var c=7; d=4')()
console.log(window.c, window.d);
// => undefined 4
You can enumerate any variables in global scope as properties of window (or global). You cannot enumerate local variables in any way.
If you invoke eval() directly, then it runs in the local scope. So, if the script defines new variables, then they are defined in the local scope. There is no built-in way to iterate local scope variables as Javascript does not provide a way to iterate the variables defined within the local scope (unless the local scope happens to also be the global scope).
If you invoke eval via an indirect reference such as this:
var geval = eval;
geval("some code here");
Then, code is evaluated at the global scope and any variables defined within the script become new globals.
You can see this explained on MDN.
Note: The rules are a bit different in strict mode.
If you do
eval(console.log(this));
the response is the global window object, so the local scope of evals appears to be inaccessible.
EDIT: It ends up the result is undefined as shown by DJDavid98:
eval("console.log('call resulted in: "+console.log(this)+"')");
You can make evals store variables globally in a few ways. The first is by referencing the eval (as shown by #jfriend00) like so:
var geval = eval;
geval("some code here");
The other way of making a variable global is by removing the var from in front, like so:
eval("mrglobal = 'hey'; var local = 'can't find me'")
console.log(window["mrglobal"]); //outputs hey
console.log(window["local"]); //outputs undefined
Knowing this, a better solution can be found:
Here's some input and output:
INPUT:
var mrlocal = "hey neighbor";
mrglobal = "just passing through"
if(true) {
mrlocal = mrglobal
}
OUTPUT:
var window.evals[0].mrlocal = "hey neighbor";
mrglobal = "just passing through"
if(true) {
window.evals[0].mrlocal = mrglobal
}
And for the function: One can regex whatever they are about to eval and add global references for the local variables, like so:
var evalIndex = window.evals.length;
window.evals[evalIndex] = {};
var evalPrefix = "window.evals["+evalIndex+"].";
var localVars = [];
var scripts = initMe.getElementsByTagName("script");
for(var s = 0; s < scripts.length; s++) {
var rex = /(var.+(;|\n)|(\{(.|\n)+?\}))/g;
var localVarRex = scripts[s].innerHTML.match(rex);
for(i in localVarRex) {
var match = localVarRex[i];
if(match.charAt(0) != '{') {
var var_name = match.replace(/(var +|( ?)+=.+\n?)/g, '');
var_name = var_name.replace(/[\n\r]/g, '');
localVars.push(var_name);
}
}
}
console.log(localVars);
for(var s = 0; s < scripts.length; s++) {
var textToEval = scripts[s].innerHTML;
for(i in localVars) {
var match = localVars[i];
var replace = evalPrefix+match;
var rex = new RegExp("(var)?[^\.]"+match, "g");
textToEval = textToEval.replace(rex, function(replaceMe) {
var out = replaceMe;
if(replaceMe.charAt(0) != '.') {
console.log('match::"'+replaceMe+'"');
out = replace;
if(replaceMe.charAt(0) != 'v')
out = replaceMe.charAt(0)+replace;
}
return out;
});
eval(textToEval);
}
}
So, with this trick, you can bring in outside html, eval it's scripts, and keep all the local variables.
Years later, I finally found the solution:
with (new Proxy()) { eval() }
The codebase I was working on is long dead, but that proxy will catch it all.
My snake game is leaving a trail everywhere it goes, rather than moving properly: http://jaminweb.com/Snake.html
(Move it with the arrow keys)
I'm wondering whether this might be a problem of scope.
The relevant code is
var temp = this.body[0].clone();
// ....
this.body[0].translate(this.dx, this.dy);
for (var i = 1, j = this.body.length; i < j; ++i)
{
var lastBB = temp.getBBox();
var thisBB = this.body[i].getBBox();
temp = this.body[i].clone();
this.body[i].translate(lastBB.x-thisBB.x,lastBB.y-thisBB.y);
}
I'm wondering, dees
temp = this.body[i].clone();
inside the for loop create a new variable or does Javascript look outside to see if there's already one? I assumed the latter.
temp = this.body[i].clone(); creates a new object, thus you are creating new objects that don't get translated.
And as #MikeW pointed out in the comments, there is no for block scope in JavaScript; scoping is either global or limited to a function. So, temp in your code is the same variable both inside and outside of the for loop.
the this variable always points to the context that it is defined in.
function Constructor1
{
this.x = 1; // points to the objects instantiated by Constructor1
}
var a = new Constructor1;
a.x = 1; // `this` points to a
var b = new Constructor1;
b.x = 1; // `this` points to b
function func()
{
return this; // points to the calling function, returns itself
}
func() will return the function itself
Javascript uses functional scope as opposed to block scope.
Is it possible to define a global variable in a JavaScript function?
I want use the trailimage variable (declared in the makeObj function) in other functions.
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script type="text/javascript">
var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
function makeObj(address) {
**var trailimage = [address, 50, 50];**
document.write('<img id="trailimageid" src="' + trailimage[0] + '" border="0" style=" position: absolute; visibility:visible; left: 0px; top: 0px; width: ' + trailimage[1] + 'px; height: ' + trailimage[2] + 'px">');
obj_selected = 1;
}
function truebody() {
return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
}
function hidetrail() {
var x = document.getElementById("trailimageid").style;
x.visibility = "hidden";
document.onmousemove = "";
}
function followmouse(e) {
var xcoord = offsetfrommouse[0];
var ycoord = offsetfrommouse[1];
var x = document.getElementById("trailimageid").style;
if (typeof e != "undefined") {
xcoord += e.pageX;
ycoord += e.pageY;
}
else if (typeof window.event != "undefined") {
xcoord += truebody().scrollLeft + event.clientX;
ycoord += truebody().scrollTop + event.clientY;
}
var docwidth = 1395;
var docheight = 676;
if (xcoord + trailimage[1] + 3 > docwidth || ycoord + trailimage[2] > docheight) {
x.display = "none";
alert("inja");
}
else
x.display = "";
x.left = xcoord + "px";
x.top = ycoord + "px";
}
if (obj_selected = 1) {
alert("obj_selected = true");
document.onmousemove = followmouse;
if (displayduration > 0)
setTimeout("hidetrail()", displayduration * 1000);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<img alt="" id="house" src="Pictures/sides/right.gif" style="z-index: 1; left: 372px;
top: 219px; position: absolute; height: 138px; width: 120px" onclick="javascript:makeObj('Pictures/sides/sides-not-clicked.gif');" />
</form>
</body>
</html>
As the others have said, you can use var at global scope (outside of all functions and modules) to declare a global variable:
<script>
var yourGlobalVariable;
function foo() {
// ...
}
</script>
(Note that that's only true at global scope. If that code were in a module — <script type="module">...</script> — it wouldn't be at global scope, so that wouldn't create a global.)
Alternatively:
In modern environments, you can assign to a property on the object that globalThis refers to (globalThis was added in ES2020):
<script>
function foo() {
globalThis.yourGlobalVariable = ...;
}
</script>
On browsers, you can do the same thing with the global called window:
<script>
function foo() {
window.yourGlobalVariable = ...;
}
</script>
...because in browsers, all global variables global variables declared with var are properties of the window object. (The new let, const, and class statements [added in ES2015] at global scope create globals that aren't properties of the global object; a new concept in ES2015.)
(There's also the horror of implicit globals, but don't do it on purpose and do your best to avoid doing it by accident, perhaps by using ES5's "use strict".)
All that said: I'd avoid global variables if you possibly can (and you almost certainly can). As I mentioned, they end up being properties of window, and window is already plenty crowded enough what with all elements with an id (and many with just a name) being dumped in it (and regardless that upcoming specification, IE dumps just about anything with a name on there).
Instead, in modern environments, use modules:
<script type="module">
let yourVariable = 42;
// ...
</script>
The top level code in a module is at module scope, not global scope, so that creates a variable that all of the code in that module can see, but that isn't global.
In obsolete environments without module support, wrap your code in a scoping function and use variables local to that scoping function, and make your other functions closures within it:
<script>
(function() { // Begin scoping function
var yourGlobalVariable; // Global to your code, invisible outside the scoping function
function foo() {
// ...
}
})(); // End scoping function
</script>
Just declare
var trialImage;
outside. Then
function makeObj(address) {
trialImage = [address, 50, 50];
...
...
}
If you read the comments there's a nice discussion around this particular naming convention.
It seems that since my answer has been posted the naming convention has gotten more formal. People who teach, write books, etc. speak about var declaration, and function declaration.
Here is the additional Wikipedia post that supports my point: Declarations and definitions
...and to answer the main question. Declare variable before your function. This will work and it will comply to the good practice of declaring your variables at the top of the scope :)
Just declare it outside the functions, and assign values inside the functions. Something like:
<script type="text/javascript">
var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage = null ; // Global variable
function makeObj(address) {
trailimage = [address, 50, 50]; // Assign value
Or simply removing "var" from your variable name inside function also makes it global, but it is better to declare it outside once for cleaner code. This will also work:
var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
function makeObj(address) {
trailimage = [address, 50, 50]; // Global variable, assign value
I hope this example explains more: http://jsfiddle.net/qCrGE/
var globalOne = 3;
testOne();
function testOne()
{
globalOne += 2;
alert("globalOne is :" + globalOne );
globalOne += 1;
}
alert("outside globalOne is: " + globalOne);
testTwo();
function testTwo()
{
globalTwo = 20;
alert("globalTwo is " + globalTwo);
globalTwo += 5;
}
alert("outside globalTwo is:" + globalTwo);
No, you can't. Just declare the variable outside the function. You don't have to declare it at the same time as you assign the value:
var trailimage;
function makeObj(address) {
trailimage = [address, 50, 50];
There are three types of scope in JavaScript:
Global Scope: where the variable is available through the code.
Block Scope: where the variable is available inside a certain area like a function.
Local Scope: where the variable is available in more certain areas, like an if-statement
If you add Var before the variable name, then its scope is determined where its location is
Example:
var num1 = 18; // Global scope
function fun() {
var num2 = 20; // Local (Function) Scope
if (true) {
var num3 = 22; // Block Scope (within an if-statement)
}
}
num1 = 18; // Global scope
function fun() {
num2 = 20; // Global Scope
if (true) {
num3 = 22; // Global Scope
}
}
It depends on what you intend by the word "global". If you want global scope on a variable for function use (which is what the OP wants) then you should read after the edit. If you want to reuse data from page to page without the use of a server, you should be looking to you use sessionStorage.
Session Storage
var Global = 'Global';
function LocalToGlobalVariable() {
// This creates a local variable.
var Local = '5';
// Doing this makes the variable available for one session
// (a page refresh - it's the session not local)
sessionStorage.LocalToGlobalVar = Local;
// It can be named anything as long as the sessionStorage
// references the local variable.
// Otherwise it won't work.
// This refreshes the page to make the variable take
// effect instead of the last variable set.
location.reload(false);
};
// This calls the variable outside of the function for whatever use you want.
sessionStorage.LocalToGlobalVar;
I realize there is probably a lot of syntax errors in this but its the general idea... Thanks so much LayZee for pointing this out... You can find what a local and session Storage is at http://www.w3schools.com/html/html5_webstorage.asp. I have needed the same thing for my code and this was a really good idea.
Scope
As of (I believe) 2015, a new "standard" for javascript (if you will) was introduced. This standard introduced many new ideas into javascript, one of them being the implementation of scope.
https://www.w3schools.com/js/js_scope.asp has all the details concerning this idea, but the cliff notes:
const defines a constant.
var has "global" scope.
let has "function" or "block" scope.
Classic example:
window.foo = 'bar';
A modern, safe example following best practice by using an IIFE:
;(function (root) {
'use strict'
root.foo = 'bar';
)(this));
Nowadays, there's also the option of using the WebStorage API:
localStorage.foo = 42;
or
sessionStorage.bar = 21;
Performance-wise, I'm not sure whether it is noticeably slower than storing values in variables.
Widespread browser support as stated on Can I use....
It is very simple. Define the trailimage variable outside the function and set its value in the makeObj function. Now you can access its value from anywhere.
var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage;
function makeObj(address) {
trailimage = [address, 50, 50];
...
}
Yes, You can. Just don't use var, don't use let. Just initialize variable and it will be automaticly assigned global:
function firstFunction() {
if (typeof(testVar) === "undefined") {testVar = 1;} //initializing variable if not initialized
testVar += 1;
console.log('Test variable inside 1st function: '+testVar);
}
function secondFunction() {
testVar += 1;
console.log('Test variable inside 2nd function: '+testVar);
}
firstFunction();
secondFunction();
testVar += 1;
console.log('Test variable outside: '+testVar);
Global variables are declared outside of a function for accessibility throughout the program, while local variables are stored within a function using var for use only within that function’s scope. If you declare a variable without using var, even if it’s inside a function, it will still be seen as global.
References = https://www.freecodecamp.org/news/global-variables-in-javascript-explained/
All variables declared without "var" or "let" or anything else preceding it like "const" are global. So ....
function myFunction(){
myVar = "value"; // myVar is a global variable and can be used anywhere inside <script> tags.
}
As an alternative to global vars, you may use the localstorage of browsers (if not using older versions). You can use upto 5MB of this storage.
The code would be
var yourvariablevalue = 'this is a sample value';
localStorage.setItem("yourKeyvariablename", yourvariablevalue);
and this can be retrieved any time, even after you leave and open it at another time.
var yourvariablevalue = localStorage.getItem("yourKeyvariablename");
Hope this would help you !
If you are making a startup function, you can define global functions and variables this way:
function(globalScope)
{
// Define something
globalScope.something()
{
alert("It works");
};
}(window)
Because the function is invoked globally with this argument, this is global scope here. So, the something should be a global thing.
Here is sample code that might can be helpful.
var Human = function() {
name = "Shohanur Rahaman"; // Global variable
this.name = "Tuly"; // Constructor variable
var age = 21;
};
var shohan = new Human();
document.write(shohan.name + "<br>");
document.write(name);
document.write(age); // Undefined because it's a local variable
Here I found a nice answer: How can one declare a global variable in JavaScript?
To use the window object is not a good idea. As I see in comments,
'use strict';
function showMessage() {
window.say_hello = 'hello!';
}
console.log(say_hello);
This will throw an error to use the say_hello variable we need to first call the showMessage function.
Here is another easy method to make the variable available in other functions without having to use global variables:
function makeObj() {
// var trailimage = 'test';
makeObj.trailimage = 'test';
}
function someOtherFunction() {
document.write(makeObj.trailimage);
}
makeObj();
someOtherFunction();