Changing global Variable from within function - javascript

Here im having a bit of an issue with this very simple script Ive written up. The aim for this script is to simply reduce the given number by one each time the button is clicked. I cannot appear to do this.. My global variable being the Number=100 doesnt appear to change, or change more than once.. Apologies for not being able to explain this well.
Here is the part im working on..:
<script>
var Number = 100; // Number i want changed and to keep changing each button click
function outcome() { // Button calls this function
Number = Number - 1; // Tries to change Global Number.. :/
}
document.write(Number); // Has the Number written in the document
</script>

Yes, conceptually this is right. Only you are not calling the function, at least not before writing Number to the document.
Btw, Number is the global reference to the Number constructor so you should use another variable name, lowercase at best.
var num = 100;
function outcome() {
num--;
}
outcome();
document.write(num); // 99
or
<script>
var num = 100;
function outcome() {
num--;
alert(num);
}
</script>
<button onclick="outcome()">Decrease!</button>
(Demo at jsfiddle.net)

You have to call your function:
<script>
var Number=100
function outcome(){
Number=Number-1
}
outcome(); // call the function here
document.write(Number)
</script>
or don't use a function in the first place:
<script>
var Number=100
Number=Number-1
document.write(Number)
</script>

Related

Change javascript variable on others script outcome

I need a way where I can change the variable of a jave script function on the outcome of a different function which gets executed on a input click.
Example of the input:
<input type="image" value="74" onclick="WeaponType(this);GetDamage(74);return false;" class="CompactPistol" src=".\Weapons\Bornheim_No_3_Extended.png" alt="Bornheim No.3 Extended">
<span style="color:whitesmoke">Bornheim No. 3 Extended</span>
(I could also change the 'GetDamage' function input to 'this' instead of the value directly and then just change the function output to use the attribute 'value'. In my case it doesn't really matter as the value of one picture is set.)
My script that needs the variable currently looks like this:
<script id="ResultDamage">
function GetDamage(x) {
document.getElementById("DamageDealt").innerHTML = x;
}
</script>
This ofc only outputs the value of the function. But the value needs to be used in a more complicated calculation
What I f.e. also already tried was this:
<script id="ResultDamage">
function GetDamage(x) {
var z
z = x;
return z;
}
var d = z;
document.getElementById("DamageDealt").innerHTML = d;
</script>
and this:
<script id="ResultDamage">
function GetDamage(x) {
return x;
}
var d = GetDamage();
document.getElementById("DamageDealt").innerHTML = d;
</script>
Which gives me 'undefined'
Any help is appreciated.
As I am quite new to this keeping it simple would probably the best (if there is a simple solution)
Based on comments on the question above...
If you just need to store a value globally on the page then you can declare a variable outside of the function and set its value within any function. For example:
var a = 0;
var b = 0;
// etc.
function GetDamage(x) {
a = x;
// perform a calculation as needed
// write a result to the page as needed
}
In this case the values of a and b are stored at the page level and available to other functions, persist their values between function calls, etc. So you can have separate functions that also use those values for their own calculations.

Javascript on click event not reading else statement or variables

I'm trying to make a click handler that calls a function; and that function gets a string and basically slices the last character and adds it to the front, and each time you click again it should add the last letter to the front.
It seem so easy at first that I thought I could just do it using array methods.
function scrollString() {
var defaultString = "Learning to Code Javascript Rocks!";
var clickCount = 0;
if (clickCount === 0) {
var stringArray = defaultString.split("");
var lastChar = stringArray.pop();
stringArray.unshift(lastChar);
var newString = stringArray.join('');
clickCount++;
} else {
var newArray = newString.split("");
var newLastChar = newArray.pop();
newArray.unshift(newLastChar);
var newerString = newArray.join("");
clickCount++;
}
document.getElementById('Result').innerHTML = (clickCount === 1) ? newString : newerString;
}
$('#button').on('click', scrollString);
Right now it only works the first time I click, and developer tools says newArray is undefined; also the clickCount stops incrementing. I do not know if it's an issue of scope, or should I take a whole different approach to the problem?
Every time you click you are actually reseting the string. Check the scope!
var str = "Learning to Code Javascript Rocks!";
var button = document.getElementById("button");
var output = document.getElementById("output");
output.innerHTML = str;
button.addEventListener("click", function(e){
str = str.charAt(str.length - 1) + str.substring(0, str.length - 1);
output.innerHTML = str;
});
button{
display: block;
margin: 25px 0;
}
<button id="button">Click Me!</button>
<label id="output"></label>
It is, in fact, a scoping issue. Your counter in inside the function, so each time the function is called, it gets set to 0. If you want a counter that is outside of the scope, and actually keeps a proper count, you will need to abstract it from the function.
If you want to keep it simple, even just moving clickCount above the function should work.
I do not know if it's an issue of scope
Yes, it is an issue of scope, more than one actually.
How?
As pointed out by #thesublimeobject, the counter is inside the function and hence gets reinitialized every time a click event occurs.
Even if you put the counter outside the function, you will still face another scope issue. In the else part of the function, you are manipulation a variable (newString) you initialized inside the if snippet. Since, the if snippet didn't run this time, it will throw the error undefined. (again a scope issue)
A fine approach would be:
take the counter and the defaultString outside the function. If the defaultString gets a value dynamically rather than what you showed in your code, extract its value on page load or any other event like change, etc. rather than passing it inside the function.
Do not assign a new string the result of your manipulation. Instead, assign it to defaultString. This way you probably won't need an if-else loop and a newLastChar to take care of newer results.
Manipulate the assignment to the element accordingly.
You can use Javascript closure functionality.
var scrollString = (function() {
var defaultString = "Learning to Code Javascript Rocks!";
return function() {
// convert the string into array, so that you can use the splice method
defaultString = defaultString.split('');
// get last element
var lastElm = defaultString.splice(defaultString.length - 1, defaultString.length)[0];
// insert last element at start
defaultString.splice(0, 0, lastElm);
// again join the string to make it string
defaultString = defaultString.join('');
document.getElementById('Result').innerHTML = defaultString;
return defaultString;
}
})();
Using this you don't need to declare any variable globally, or any counter element.
To understand Javascript Closures, please refer this:
http://www.w3schools.com/js/js_function_closures.asp

Javascript variable is undefined

<html>
<head>
<title>Array of images</title>
<script type="text/javascript">
var myPics = new Array[3];
myPics[0] = "./img/blue.png";
myPics[1] = "./img/red.png";
myPics[2] = "./img/yellow.png";
var counter = 0;
function preImg(){
alert(counter);
if(counter == 0)
counter = 4;
counter --;
alert(counter);
document.getElementById("coloredImg").src = myPics[counter];
}
function nextImg(){
if(counter == 3)
counter = -1;
counter ++;
document.getElementById("coloredImg").src = myPics[counter];
}
</script>
</head>
<body>
<img src="./img/blue.png" id="coloredImg" alt="Image not found"/>
<input type="button" onclick="preImg()" value="Previous"/>
<input type="button" onclick="nextImg()" value="Next"/>
</body>
</html>
The problem I encounter is that my counter variable is undefined inside the function. For example when I call the function preImg it alerts me with undefined (when it should be just 0) and the second alert show NaN when it should be a 3. Why my function doesnt recognize my "var counter" it is global isnt it? Do you think the same happens with the variable mypics. Thanks!
new Array[3];
should be
new Array(3);
But rather, use the square bracket notation to create an array (there's no need to specify the length either):
var myPics = [];
Why use this syntax you may ask? There are many reasons:
[] is a faster and shorter way of creating an array.
The Array constructor can be overridden while a syntactical construct like this cannot.
It's much easier to spot in code, making debugging easier.
It has the ability to take a single element (i.e [5]) and not interpret it as the length of the array, a common problem with the cumbersome Array constructor.
var myPics = new Array[3]; should be var myPics = new Array(3);
JsFiddle: http://jsfiddle.net/cbJAc/
Simple slideshow object using a closure over element, pics and counter:
function Slideshow(element, pics) {
var counter = 0;
this.nextImg = function () {
element.src = pics[counter];
counter = (counter + 1) % pics.length;
}
this.nextImg(); // init
}
usage:
var show = new Slideshow(
document.getElementById("coloredImg"),
["./img/blue.png", "./img/red.png", "./img/yellow.png"]
);
show.nextImg(); // red
show.nextImg(); // yellow
show.nextImg(); // blue
Closures make sure that every variable that's in scope when a function is defined will still be in scope when the function is called (or called again). This standard JavaScript technique elegantly solves your counter issue.
Using a modulus based calculation lets the counter repeat the sequence 0,1,2 (in this example).
Edit: Assume you would want to switch to a new image every three seconds:
setInterval(show.nextImg, 3000);

Help with adding variable to self and random number (javascript)

I am making a simple dice roller, which seems like a good first project to me, and may help others learn javascript as well, and when you roll a die (with a button), it is supposed to add to the total (there is a clear button), but it says NaN. Here is my code:
<html>
<body>
<script type="text/javascript">
function load()
{
document.getElementById("press").value=" "
var x=0
}
function d6()
{
var x=x+(Math.floor((Math.random() * 6) + 1));
document.getElementById("press").value=(x)
}
load()
</script>
<input type="button" value="Roll d6" onclick="d6()"/>
<input type="text" id="press"/>
</b>
<input type="button" value="Clear" onclick="load()"/>
</body>
</html>
Help would be greatly appriciated.
Thanks!
This is happenning because variable x is not initialised when you are using it in d6(). The scope of the 2 functions is different.
You need x to be a global variable. For that, use the following code structure:
x = 0
function load() { ... }
function d6() { ... }
Remember that when you declare a variable with the keyword 'var' preceding it, the variable is considered local. A variable without a 'var' is considered global.
Your x variables are local to the functions. change x to be a global variable:
var x;
function load() { ... }
function d6() { ... }
When using JavaScript it is important to consider the scope of names and values. Consider the difference between this:
var x = 2;
function assignX(v) {
x = v;
}
print(x); // 2
assignX(3);
print(x); // 3
and this:
function assignX(v) {
var x = v;
}
print(x); // undefined
assignX(3);
print(x); // undefined
In the first example x exists in the global scope which encloses all names and values. In the second example x only exists within the function assignX.

Using a global variable in JavaScript

How do I do this?
My code is something like this:
var number = null;
function playSong(artist, title, song, id)
{
alert('old number was: ' + [number] + '');
var number = '10';
alert('' + [number] + '');
}
The first alert always returns 'old number was: ' and not 10. Shouldn't it return 10 on both alerts on the second function call?
By using var when setting number = '10', you are declaring number as a local variable each time. Try this:
var number = null;
function playSong(artist, title, song, id)
{
alert('old number was: ' + [number] + '');
number = '10';
alert('' + [number] + '');
}
Remove the var in front of number in your function. You are creating a local variable by
var number = 10;
You just need
number = 10;
The problem is that you're declaring a new variable named number inside of the function. This new variable hides the global number variable, so the line number = 10 assigns only to this new local variable.
You need to remove the var keyword from var number = 10.
Like in C, you need to define your variable outside of the function/method to make it global.
var number = 0;
function playSong(artist,title,song,id)
{
alert('old number was: '+[number]+'');
number = '10';
alert(''+[number]+'');
}
Let me explain in detail. To declare global variables and local variables in JavaScript
var firstNumber = 5; // Local variable
secondNumber = 10; // Global variable or window object
When your program is like this
var number = 1;
function playSong() {
alert(number);
var number = 2;
alert(number);
}
As per the JavaScript compiler, all declarations/initializations of variables will move to the top. This concept is called hoisting.
As per the compiler, the program will execute like:
var number; // Declaration will move to top always in Javascript
number = 1;
function playSong() {
var number;
alert(number); // Output: undefined - This is a local variable inside the function
number = 2;
alert(number); // Output: 2
}
If you need to access the global variable inside the function, use window.number.
var number = 1;
function playSong() {
var number = 2;
alert(window.number); // Output: 1 - From a global variable
alert(number); // Output: 2 - From local variable
}
You can also access it in any function like window.number, after removing var inside the function.
I’ve come across this answer in 2020 and after searching some more online I have found that apparently in the JavaScript definitions if you place variables outside of functions or even create a file called globals.js and just put all your globally required variables in that file, make that file the first user .js file in your script tags after jQuery and any other plugins you need, globals will load before your other scripts and allow you to call variables from globals.js within any script on the page.
W3C JavaScript Scope
I have tested this theory within a PHP application that I am building and I have been able to call variables from the globals.js file within a page that is loaded via Ajax to a jconfirm dialog for a troubleshooting wizard to set up the return values for when the dialog is closed.

Categories

Resources