How to permanently change var? - javascript

So, I have a var set in a function and a array(called "card_idx) set up, and I want the var be set to 0 until a certain number is reached in the array but the number doesn't go up in order (1..2..3..4 extra). It jumps around depending on how the person plays ( so it can be like...1...2...2.1....5....3.2...). And I want the var to be set to 0 until a specific number is reached and then it is changed to 1.
I try having it set up like:
var x=0;
if(card_idx == 3.2){
x=1
}
but the moment there no longer on 3.2 it will change back to zero, how do i make it so it will stay 1?

While your example isn't complete enough to reproduce the problem, I imagine you may be running into trouble with variable scope.
JS variables are locally scoped to the function surrounding them, which works to your advantage here. If you declare x at the beginning of the function that goes through your data, the loop can modify it and the value will be retained after the loop completes:
function crunch(data) {
var x = 0;
data.forEach(function (item) {
if (item.index === 3.2) {
x = 1;
}
});
console.log(x);
}
If any item in data had an index of 3.2, x will be set to 1 and printed to the console at the end. The callback to forEach grabs x using closure, but this would work just the same with a for loop.
Using x within the loop, the value will not be reset until crunch returns. Every time crunch is called, x will be set to 0, may be set to 1 if an item has the right index, and will retain that value until the end of crunch.
Now, with forEach, if you were to declare x inside the loop callback rather than in crunch, it would reset every time:
function crunch(data) {
data.forEach(function (item) {
var x = 0;
if (item.index === 3.2) {
x = 1;
}
});
}
Because var operates at the function level, this will not keep its value and will be 0 for every item.

You could try this. Use an extra boolean to check if x has ever been set.
Be aware that your variables are outside the iteration.
var x = 0;
var hasSet = false;
// start looping
if (card_idx == 3.2 && hasSet = false) {
x = 1
hasSet = true;
}
Or maybe (if your question was more clear) this will work out too.
var x = 0;
// start looping
if (card_idx == 3.2 && x <= 0) {
x = 1
}

Related

iterating through and changing nodes in singly linked list

The problem is I don't understand why this code works. It works, but I just can't wrap my mind around it. Here's a function that deletes a node from a singly linked list. I feel like it shouldn't work because it's not actually changing any of the elements in the list, I'm just changing the value of a variable I have set equal to something in the list. In other words, when I create a "runner" variable to iterate through the list, why are the changes I make to "runner" actually changing the list itself. Analogously, if I do
var x = 1
var y = x
y = 2
Obviously, x is still going to equal 1. Why isn't the same true for my Linked List "runner". In the deleteNode function below, why does changing the runner.next value actually change anything in the node or list that exists outside of the function?
function deleteNode(head, position) {
var runner = head
var counter = 0
while (runner) {
if (counter == position - 1) {
runner.next = runner.next.next
return head;
}
runner = runner.next
counter++
}
}
Its because runner is an object, and so the runner variable is a reference to that object.
for example
const x = {a:1}
const y = x;
x.a = 3
console.log(y.a) // this will print 3 also

JavaScript variable changing between two values on a regular basis [duplicate]

This question already has answers here:
Is there a better way of writing v = (v == 0 ? 1 : 0); [closed]
(31 answers)
Closed 5 years ago.
I want a variable's value regularly changing between 0 and 1. If I have a variable whose value is 0 (counter = 0), how can I increase it by 1 (counter = 1) after a few seconds, then decrease it back to 0 ( counter = 0) after another few seconds? An endless loop basically is what I want.
I'm assuming this will require setTimeout or setInterval, but I've absolutely no idea how I'd go about this. I'm very unfamiliar with the syntax; I'm very much a newbie. Does anyone have any pointers?
Thanks!
You can create an endless, timed loop by having a function that calls itself at the end via setTimeout. See below.
var count = 0;
function flip() {
count = Number(!count);
console.log(count);
setTimeout(flip, 1000);
}
flip();
A more generic approach:
// possible addition: allow user to stop the timer
const rotate = (time, vals) => {
// TODO: handle incorrect vals (non-empty array) or time (positive number)
let idx = 0;
setInterval(() => idx = (idx + 1) % vals.length, time);
return {
get val() {return vals[idx];}
}
}
const toggle = rotate(1000, [0, 1])
toggle.val //=> depends on when you call it, changes every 1000 ms
// but always either 0 or 1.
One advantage of this is that it doesn't keep the value in global scope where someone else can mess with it, but encapsulates it in a closure.
It's more generic because you can easily change the time between updates and you can choose whatever you want for values (for example, rotate(5000, ['foo', 'bar', 'baz').)
var counter = 0;
var changeCounter = function () {
counter = counter === 0 ? 1 : 0;
console.log('counter', counter);
setTimeout(changeCounter, 1000);
}
changeCounter();
This sounds like homework but try this:
var value = 0;
setInterval(
function() {
value = value===0 ? 1 : 0;
console.log('value =', value);
},
1000
);
setInterval will call the function over and over again without needing to call setTimeout over and over again.
setInterval is what you want, as documented in W3C, you should pass a function and a time interval in milliseconds on how often to execute the code.
var counter = 0;
setInterval(function(){
counter = 1 - counter;
//Do what you want with the result...
//alert(counter);
}, 1000);
https://codepen.io/paulodiogo/pen/xPPOKa?editors=1010
Not using global variable...
https://codepen.io/paulodiogo/pen/KyyMXZ

Is it Possiable to call to previous increments of a variable?

for example lets say i have a loop that is doing basic counting, while the variable is less than 16 the loop will run and at the end of the loop you add 2 to the variable and add one to a "count" variable
what i want to know is if its possible to callback to any of the previous variables for either variable for example can i count all the times count % 2 === 0?
im not quite sure if once a variable makes any kind of change if all previous versions of that variable are gone
http://codepen.io/anon/pen/Gojoxm
var two = 0;
var count = 0;
while ( two < 16) {
two += 2;
count++;
};
console.log(count);
If I understand you right, then no, you cannot. When you assign a new value to a variable, the previous value is lost.
You have to either run this loop again or store intermediate values in an array:
var values = [];
var two = 0;
while (two < 16) {
two += 2;
values.push(two);
}
console.log(values.length); // the same result
Then, you will always be able to do whatever you want with these values.
For example, you can check if there were any odd values:
var anyOddNumbers = values.some(function(x) { return x % 2 === 1; }); // false

In callback function with Javascript closure, how to access the global variable

It is simple:
I need to register an event property with a function. But in order to pass arguments to the function, I create a closure.
var x=0
function foo(bar1,bar2){
return function (){
alert (bar1+bar2);
x++;
}
}
for (var i=0;i<document.getElementsByTagName("div").length;i++) {
document.getElementsByTagName("div")[i].onclick=foo(x,i)
}
Since I have 5 div elements, and I thought it should alert like this if I click all the div from top to down:
0
2
4
6
8
but instead it output:
0
1
2
3
4
It seems like that every time in foo(x,i), x is equal to 0. How do I get foo() to access the new value of x instead of its first initiation?
You are incrementing x only within the inner function. This function is only called once an element is clicked. As a result, at the time foo is called, x is always 0. It is only incremented later when something is clicked and at that point the values of bar1 are already set (to 0).
You could do something like this instead:
var x=0
function foo(bar1){
return function (){
alert (bar1+x);
x++;
}
}
for (var i=0;i<document.getElementsByTagName("div").length;i++) {
document.getElementsByTagName("div")[i].onclick=foo(i)
}
In this way you will always use the current value of x instead of the value at the time foo was called.
You need to increment x where you increment i. Because on every iteration x is still zero thus the values you're getting 0,1,2,3,4 are actually the values of i.
In your code, you are passing the value 0 to the variable bar1 on every iteration and the only time that x increments is after you click the button not during the iteration, so if you put another alert for x in front of this alert alert (bar1+bar2); you see what i mean.
Finally to increase x on every iteration you must explicitly do it in the loop. like this:
;i++, x++)
JSFIDDLE
This would output 0,2,4,6,8 without increment x on every click.
var x = 0,
div = document.getElementsByTagName("div");
function foo(b1, b2){
return function () {
alert (b1 + b2);
}
}
for (var i = 0; i< div.length; i++, x++) {
div[i].onclick = foo(x, i);
}

Javascript Object scope

This is a simplification of something that I've come up against in a larger project so I hope it makes sense.
I have two Objects:
FirstObj = {
data : [],
init : function()
{
for(var a = 0; a < 20; a++)
{
this.data[a] = 1;
}
}
};
SecondObj = {
init : function()
{
var cell = FirstObj.data[0];
cell = 0;
}
};
I then call the two init methods and log the results:
(function(){
FirstObj.init();
SecondObj.init();
console.log(FirstObj.data);
})()
Now, I was assuming - based on my basis in Actionscript - that the log would show an Array in which the first item is a 0 and the rest all 1 but the 0 does not seem to stick.
Why does the assignment of the 0 value not succeed here and yet works fine if, instead of cell = 0 I target directly at FirstObj.data[0] = 0.
I'm guessing this is a scope thing and I can work round it but I'm trying to get a proper understanding of how JS actually handles this stuff, especially when lumping code into Objects like this (as an aside, is this a good approach in peoples general opinion?).
Thank for any help.
Numbers in JavaScript are something called primitive value types (alongside strings, booleans null and undefined).
This means, that when you do
var cell = FirstObj.data[0];
You're passing the value in FirstObj.data[0] and not a refernece to it.
What you're doing is like:
var x = 5;
var y = x; // y is now 5
y = 4; // y is 4, x is still 5.
Of course, something like FirstObj.data[0] = 0 should work.
Array indexing returns values in Javascript, not references. It means that once data[0] is assigned to cell, further modification of cell will not affect data[0].
Assigning the array itself would result in the behavior you're looking for:
SecondObj = {
init : function()
{
var cells = FirstObj.data;
cells[0] = 0; // Will also affect data[0].
}
};

Categories