There is something like this found in my javascript homework. Is this valid, or did they forget to put the braces?
var squares = [],
SIZE = 3,
EMPTY = " ",
score,
moves,
turn = "X";
There are 6 variables being declared in your code. It has nothing to do with an object.
squares is an array, size is a number (3), empty is a string ( ), score and moves are undefined and turn is a string (X)
Google javascript comma operator
EDIT: Declare variables used in scope
var doStuff = function() {
var i,
c = 2,
stuff = "stuff";
};
Rather than:
var doStuff = function() {
//some code
for( var i = 0; i <= 10; i++ ) {
//
}
//some code
var c = 2;
//some code
//some code
var stuff = "stuff";
};
As it lets developers see all the variables that are declared in that scope at a single glance, rather than having to search through the block to see what vars are being declared/used.
They didn't forget. Your teacher just didn't repeat the term 'var' for every variable.
That's the same as:
var squares = [];
var SIZE = 3;
var EMPTY = " ";
var score;
var moves;
var turn = "X";
Related
I've written a function that takes plevel (integer) and slevel (array of strings of numbers) and finds the smallest difference between plevel and a value in slevel. However, when I run the script, it is unresponsive and the debugger says that diff is undefined.
var findDiff = function findDiff(plevel, slevel) {
var diff = new Array();
for (i=0; i<=slevel.length; i++) {
sleveli = parseInt(slevel[i]);
diff.push(Math.abs(plevel-sleveli));
}
if (diff.length > 1){
diff.sort(function(a, b){return a-b});
return diff[0]
}
else{
return diff[0];
}
}
The function is invoked here:
var matches = new Array();
var newFetch = Data.find().fetch();
for(i = 0; i <= newFetch.length; i++ ){
pointsMatch = 0
var difference = findDiff(newFetch[i].level, spec.level);
pointsMatch -= (difference*3);
matches.push([newFetch[i], pointsMatch])
}
console.log(matches)
Data is a mongoDB collection. spec.level is an array of strings of numbers stored as a property in an object.
I would like to point out name space pollution, which may cause serious troubles. In my understanding, you have two cases of namespace pollution, one of it creates an endless loop.
You have actually an inner an outer loop, separated by a function. Your outer for loop:
for(i = 0; i <= newFetch.length; i++ ){
pointsMatch = 0
...
And then your inner for loop:
for (i=0; i<=slevel.length; i++) {
sleveli = parseInt(slevel[i]);
...
Because of the missing var before i, both for loop definitions are actually like this:
for (window.i=0; ...
So the inner loop overwrites the variable i the outer loop depends on to terminate. i is "polluting" namespace.
The second case is harmless:
sleveli = parseInt(slevel[i]);
Because of the missing var, this results in fact in
window.sleveli = parseInt(slevel[i]);
Better would be
var sleveli = parseInt(slevel[i]);
But this is a time bomb.
I suggest you add var to the definitions of i in the for loop.
I think the people in the comments are right; we need to see some more of your input to debug this properly. But you can simplify your code a lot by tracking the mins as you go:
var findDiff = function findDiff(plevel, slevel) {
var min = Number.MAX_SAFE_INTEGER;
for (i=0; i<slevel.length; i++) {
sleveli = parseInt(slevel[i]);
var diff = Math.abs(plevel-sleveli);
min = Math.min(min, diff)
}
return min;
}
var a = ["1", "2", "10", "17"]
var p = 6
// We're expecting 4 as the min diff
console.log(findDiff(p, a))
// ...prints out 4 :-)
http://repl.it/ceX
As Omri points out, use < not <= in your for loop.
Note - Number is not always available -- see here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
You could alternatively set the initial min to something suitably large for your likely data, like 2^10
I'm having some difficulty creating a variable with another variable in jQuery. I don't know how to write the var side of the equation. Here's what I'm trying to create:
var $counter= 0;
$('.selector').each(function(){
$counter += 1;
var newVariable-($counter) // this is where I'd like to create the new
// variable with the number from $counter at the end.
});
with the goal to creating:
newVariable-1
newVariable-2
newVariable-3...
and so on...
You could create an object to hold these values but not dynamic variables.
var $counter= 0;
var variableHolder = {};
$('.selector').each(function(){
$counter += 1;
variableHolder["newVariable-"+$counter] = ...
});
Or if you want to make global variables (which is not recommended), you could use window:
var $counter= 0;
$('.selector').each(function(){
$counter += 1;
window["newVariable-"+$counter] = ...
});
As others have pointed out, using an {} with square bracket notation will simplify this task greatly.
Something like this:
var myobj = {},
prefix = 'my_cool_var';
for(var i = 0, len = 10; i < len; i++) {
myobj[prefix + i] = undefined; // { my_cool_var + i : undefined }
}
// Setters - dot notation and square bracket
myobj.my_cool_var1 = "Hello!";
myobj['my_cool_var2'] = "Hello 2!";
// Getters - dot notation and square bracket
alert(myobj.my_cool_var1); // alerts Hello!
alert(myobj['my_cool_var2']); // alerts Hello 2!
Now, if you needed to expose the variables in a global scope (yuck - but hey, sometimes you gotta) so you don't need to specify an object (myobj), you can use window with square bracket notation in your for loop.
var prefix = 'my_global_var';
for(var i = 0, len = 10; i < len; i++) {
window[prefix + i] = undefined; // creates global, my_global_var + i = undefined
}
my_cool_var1 = "Hello!";
alert(my_cool_var1); // alerts Hello!
Finally, if you search the web deep enough, you'll find eval examples like this:
var prefix = 'my_evil_var';
for(var i = 0, len = 10; i < len; i++) {
// Don't do this. Use square bracket notation with window, if you need a global.
eval(prefix + i + '= undefined') // creates global, my_evil_var + i = undefined
}
my_evil_var = "Eval abuse is bad!!";
alert(my_evil_var1); // alerts Eval abuse is bad!!
Hope this helps!
Just make use of the json in this context,
var $counter= 0;
var $newVar = {};
$('.selector').each(function(){
$counter += 1;
$newVar['newVariable-'+ ($counter)] = null;
});
so you can access it like $newVar.newVariable-1,.. $newVar.newVariable-N And please note that this is the best practice, we could do as you asked by accessing the window object, but that is not recommended.
Can someone explain why this for...loop doesn't work? (it should write all checked checkboxes but it writes only the last checked)
function Matula()
{
var x = document.getElementsByTagName("body")[0];
var y = document.createElement("p");
var g = document.createTextNode("Vasa pizza bude obsahovat:");
y.appendChild(g);
x.appendChild(y);
var swag = document.forms["lol"].matej.length;
for (var i = 0; i < swag; i++)
{
if (document.forms["lol"].matej[i].checked)
{
var torko = document.getElementsByTagName("body")[0];
var q = document.createElement("p");
var w = document.createTextNode(document.forms["lol"].matej[i].value);
q.appendChild(w);
torko.appendChild(q);
return mocny = 0
}
};
}
return mocny = 0
exits the function , so for it loops only once, put it outside for loop
There is a return statement in your if block. This will essentially break the loop after the first time it goes inside the if. So that means only value of one check box will be print out.
I have no idea as to what that is supposed to do as it is awfuly confusing will all those var names. But your return inside your if, which inside your for loop, doesn't seem right.
You should put that at the last line of your function.
A cleaner code could look like this:
function Matula() {
var body = document.body;
addParagraph(body, "Vasa pizza bude obsahovat:");
var allToppings = document.forms["lol"].matej;
var toppingsCount = allToppings.length;
for (var i = 0; i < toppingsCount; i++) {
if (allToppings[i].checked) {
addParagraph(body,allToppings[i].value);
}
}
}
function addParagraph(body, textToAdd) {
var p = document.createElement("p");
p.appendChild(textToAdd);
body.appendChild(y);
}
Typed off my head, might contain typos
Makes it so much easier to read. Btw. Bracket position does make a difference (it isn't Java), so keep it on the same line (Google the reasons) Does it work for you?
I want my code to display 170, 122 . All the values have been set in Javascript but still I am not getting the output.
<!DOCTYPE html>
<html>
<body>
<button onclick="UidToPost()">Get It</button>
<script>
var SetUid1 = "170";
var SetUid2 = "122";
var SetUid3 = "135";
var SetUid4 = "144";
var c = 0;
var timingToSend;
var SetUid;
function UidToPost() {
c = c + 1;
var postTo = "SetUid" + c + "";
document.getElementById("do").innerHTML = postTo;
timingToSend = setTimeout('UidToPost()', 1000);
};
</script>
<p id="do"></p>
</body>
</html>
Thanks in advance.
This is the code that I am using
var SetUid = [ "170", "122", "135", "144" ];
var c = 0;
var timingToSend;
function UidToPost() {
var postTo = SetUid[c++];
document.getElementById("do").innerHTML = postTo;
if (c < SetUid.length)
timingToSend = setTimeout(UidToPost, 1000);
};
Use an array instead of discreet variables;
var SetUid = [ "170", "122", "135", "144" ];
var c = 0;
var timingToSend;
function UidToPost() {
var postTo = SetUid[c++];
document.getElementById("do").innerHTML = postTo;
if (c < SetUid.length)
timingToSend = setTimeout(UidToPost, 1000);
};
You're trying to dynamically create the name of the variable to use with string concatenation, which is possible but not with that syntax. Since your variables are global variables, they'll be stored in the window object, so you can access them like this:
window["SetUid1"]
window["setUid2"]
//etc
With that in mind, you'll simply need to change this line:
var postTo = "SetUid" + c + "";
to:
var postTo = window["SetUid" + c];
You'll also need to handle the case where that variable doesn't exist (i.e. they click the button again after the last variable has been displayed), and take appropriate action (probably cycle back to the beginning).
Here is a working demo.
document.getElementById("do").innerHTML = window[postTo];
You should also get in the habit of avoiding the string argument version of setTimeout as it can cause security issues:
timingToSend = setTimeout(UidToPost, 1000);
I presume you'll also want to call clearTimeout() (or avoid setting the last one in the first place), e.g., after your variables are finished.
Finally, this might have been done more easily and flexibly with an array, but the above is how you can do it with your current approach.
This will do the trick:
document.getElementById("do").innerHTML = window[postTo];
You still have to perform a check for the number of vars. Now after the 4th var is displayed, the function will now write "undefined" to the screen because you keep looping.
The reason this is not working, is that you're concatenating the string SetUid with the current count c to make a string, and adding that to the innerHTML of the div.
Instead, you should hold your values in an array and use your variable c as an index to that array:
var values = [170,122,135,144]
var c = -1;
var timingToSend;
var SetUid;
function UidToPost() {
c = (c + 1) % values.length;
var postTo = "SetUid" + c + "";
document.getElementById("do").innerHTML = values[c];
timingToSend = setTimeout('UidToPost()', 1000);
}
Live example: http://jsfiddle.net/RsKZj/
--Solved by Elliot B. Thanks!
May also take int account the other modifications.
Here is the result. Thanks, everyone, for the speedy answers! http://dl.dropbox.com/u/18785762/Rust/index.html
I'm writing a game in javascript, and I want to keep the files for matching block IDs to files in a seperate .js file from the map compiler, so that I can edit things easily. However, the IDs are stored in an array, and I can't seem to get it to use the return function properly. Any help?
drawmap.js:
function drawmap() {
var images = BlockID();
var level = [
"ssssssssssssssssssssss",
"sgggggggggCCCCCdddddss",
"ssssssssss sssssss"
];
var top = 100;
var left = 100;
var mytop = top;
var myleft = left;
for (y=0; y<level.length; ++y) {
var row = level[y];
for (x=0; x < row.length; ++x) {
var c = row.charAt(x);
if(c != ' ') {
img_create(images[c], mytop, myleft);
}
mytop += 13;
myleft += 27;
}
mytop = top + (y+1)*13;
myleft = left - (y+1)*27;
}
}
mapread.js:
function BlockID() {
var IDs = new Array();
images['s'] = "Images/Block_01.png";
images['g'] = "Images/Block_02.png";
images['C'] = "Images/Block_03.png";
images['d'] = "Images/Block_04.png";
return IDs;
}
At a minimum, change this:
function BlockID() {
var IDs = new Array();
images['s'] = "Images/Block_01.png";
images['g'] = "Images/Block_02.png";
images['C'] = "Images/Block_03.png";
images['d'] = "Images/Block_04.png";
return IDs;
}
To this:
function BlockID() {
var IDs = new Object();
IDs['s'] = "Images/Block_01.png";
IDs['g'] = "Images/Block_02.png";
IDs['C'] = "Images/Block_03.png";
IDs['d'] = "Images/Block_04.png";
return IDs;
}
There are a couple fixes to point out. First, images is not defined in your original function, so assigning property values to it will throw an error. We correct that by changing images to IDs. Second, you want to return an Object, not an Array. An object can be assigned property values akin to an associative array or hash -- an array cannot. So we change the declaration of var IDs = new Array(); to var IDs = new Object();.
After those changes your code will run fine, but it can be simplified further. You can use shorthand notation (i.e., object literal property value shorthand) to create the object and return it immediately:
function BlockID() {
return {
"s":"Images/Block_01.png"
,"g":"Images/Block_02.png"
,"C":"Images/Block_03.png"
,"d":"Images/Block_04.png"
};
}
Your BlockID function uses the undefined variable images, which will lead to an error. Also, you should not use an Array here - JavaScripts key-value-maps are plain objects:
function BlockID() {
return {
"s": "Images/Block_01.png",
"g": "Images/Block_02.png",
"C": "Images/Block_03.png",
"d": "Images/Block_04.png"
};
}
neater:
function BlockID() {
return {
"s":"Images/Block_01.png",
"g":"Images/Block_02.png",
"C":"Images/Block_03.png",
"d":"Images/Block_04.png"
}
}
or just
var images = {
"s":"Images/Block_01.png",
"g":"Images/Block_02.png",
"C":"Images/Block_03.png",
"d":"Images/Block_04.png"
}
Taking in consideration that in JavaScript Array is object too this can be written as:
function BlockID() {
return new Array(
"Images/Block_01.png",
"Images/Block_02.png",
"Images/Block_03.png",
"Images/Block_04.png"
);
}
This code will display content of array in browser's window
window.onload=function(){
var s="";
var ar = BlockID(); //function return array
for(el in ar){
s+=ar[el]+"</br>";
}
document.body.innerHTML=s;
};