Dynamic Javascript - Is This Valid? - javascript

can someone tell me if this is valid javascript? I know you couldnt do this sort of thing in c# but js is a much looser language..
var arrayToUse = "arr" + sender.value;
for (i = 0; i <= arrayToUse.length; i++) {
// something..
}
specifically - the dynamic generation of the array name..
update..
so i have an array called arrMyArray which is initialised on document ready. sender.value = "MyArray" - but could be something else eg MyArray2
I want to dyanimcally iterate over the array that is indicated by the sender.value value.

Yes, this is entirely valid.
arrayToUse will be a string (regardless of the value of sender.value — it will be converted to a string), and i will iterate from 0 to the string's length).
One minor note: it should be for (**var** i = 0; …), otherwise i will be treated as a global variable, which will almost certainly end badly if you've got multiple loops running at the same time.
Edit: you want to get the array based on the name? In that case you've got to look it up in whatever context the array is defined.
If it's a global array, use window.
For example:
var arrayName = "arr" + sender.value;
var array = window[arrayName];
…

To get a variable name defined by a variable, you need to use eval, like so:
var arrayToUse = eval("arr" + sender.value);
However, you must be very careful with this, because controlling sender.value would allow someone to hijack your entire application this way. You should usually try to find another solution.
If the variable is defined at the globally, you can look it up as window["arr" + sender.value] instead. This is still not ideal, but is less of a security risk.

What you need to do is access a variable with the name "arr" + sender.value. Accessing the variable whose contents are "arr + sender.value doesn't do what you want -- that's just a string.
To access the variable with that name, you can look it up as a global (globals are members of the window object in the browser):
window["arr" + sender.value]
This is safer and faster than using eval() because it doesn't run code in a JavaScript execution context to evaluate the string -- it just looks up a variable in the window object with that name.

Related

When do I need to create a new variable within a function?

I'm a new learner of JavaScript, and when I get to learn the way of using a function. It sometime confuses me on why we should declare a new variable and add the variable to the action we want to execute. Let's look into the code.
function reverse(word){
Array.from(word);
let reverseWord='';
for(i = word.length-1; i >= 0; i--) {
reverseWord += word[i];
}
return reverseWord;
}
I'm sure you know this one of the way of reversing string in javascript, my question is:
Why do we need to declare a new variable within the function, when should we declare it?
Why can't I just type console.log(word[i]);?
What does it mean by wordLength+=word[i];?
Why should we return the new variable(wordLength), instead of the function(reverse) after the loop?
Why do we need to declare a new variable within the function...
Because you need a place to store the reversed word as you build it. (Note: wordLength isn't a good name for that variable. It doesn't contain the word's length. It contains the characters of the reversed word.)
...when should we declare it?
Any time before you first need it.
Why can't I just type console.log(word[i]);?
Because the goal of the exercise is to build a string containing the reversed word, not just to output it. (And because console.log writes a new line each time you call it.)
What does it mean by wordLength+=word[i];?
That adds the character in word[i] to the end of wordLength. For instance, if the word is "start", wordLength starts out with "", then gets "t" added to it to make it "t", then gets "r" added to it to make "tr", and so on.
(+= is a shorthand way to write wordLength = wordLength + word[i];. There are several of these compound assignment operators, most of them for math: -=, *=, etc.)
Side note: The Array.from call in your code isn't doing anything useful. It's creating an array, but then throwing that array away because nothing uses the return value. The rest of the code is using the string you receive in word.
Why do we need to declare a new variable within the function, when should we declare it?
Vars is a place to store data. If your algorithm requires keeping some data to use it later you need vars. Also well named variables is a good way to create easy-to-understand code
Why can't I just type console.log(word[i]);?
You can, but it will do nothing useful. Your goal is to build a string and return it. Usage of your function will be something like
const word = getSomeText()
const reversedText = reverse(word)
doSomeStuff(reversedText) // whatever, send it online, or render it on screen some fancy way, not in the console.
So you need to return actual string, not to solve a puzzle and show the answer whatever way you like
Why should we return the new variable(wordLength), instead of the function(reverse) after the loop?
Because it contains reversed word and you function supposed to return it. there is rare complicated occasions when a function returning itself is useful, but it has nothing in common with your task
Why do we need to declare a new variable within the function, when should we declare it?
Variable is required to store the data value that can be changed later on. In your case wordLength variable is required to store the reverse string.
It's best to declare variables when you first use them to ensure that they are always initialized to some valid value.
Why can't I just type console.log(word[i])
console.log() is used just to print the output but will not use if you want to return something and as per your statement it will just print the word[i] not a whole reverse string.
What does it mean by wordLength+=word[i]
It means you are concatenating the each iteration word[i] into a wordLength variable.
wordLength+=word[i] is a shorthand for wordLength = wordLength + word[i]. If the left hand side of the + operator is a string, JavaScript will coerce the right hand side to a string.
Why should we return the new variable(wordLength), instead of the function(reverse) after the loop ?
Because this is what you expected from the function. It returns the reversed string and function should return it.

Give eval a value in JavaScript

very basic JavaScript programmer here!
I was busy on some code with variables that look like this:
blocktype1;
blocktype2;
blocktype3;
blocktype4;
... //everything between blocktype4 and blocktype70, the three dots are not actual code!
blocktype70;
Now I was using eval() in a function where a value was given to one of the blocktype variables. The blocktype depended on the variable "number".
This is what I had for that part:
eval("blocktype" + number) = 3
What I want is, say "number" is 27, then I want the variable blocktype27 to get a value of 3.
When I check the console it says:
ReferenceError: Invalid left-hand side in assignment
Could anyone possibly help me?
I would prefer just vanilla JavaScript and still the use of eval.
Thank you for your time!
The 'correct' solution would probably be to use an Array which is ideal for sequences and are accessible by index.
var number = 1;
var val = 3;
var blocktype = []; // so clean
blocktype[number] = val;
However, properties can be accessed as with the bracket notation as well. This assumes the variables are in global scope and are thus properties of the global (window) object.
var blocktype1; // .. etc
window["blocktype" + number] = val;
The problem with the eval is that is effectively the same as doing f() = 3 which does not make sense: only variables/properties can be assigned to1.
However eval is a built-in function and the results of a function cannot be assigned to, per the error message. It could be written as
var blocktype1; // .. etc (see dandavis' comment)
eval("blocktype" + number + " = " + val);
// What is actually eval'd is:
// eval("blocktype1 = 3")
which quickly exposes a flaw with eval. If val was the string "Hello world!" with would result in eval("blocktype1 = Hello world!") which is clearly invalid.
1 For the gritty: the left-hand side of an assignment has to be a Reference Specification Type, which is a more wordy way of describining the above behavior. (It is not possible for a JavaScript function to return a RST, although it could technically be done for vendor host objects.)
Feel free not to accept this, since it's specifically not using eval(), but:
You can allocate an array of size 71 like so:
var blocktype = new Array(71);
(your number values apparently start at 1, so we'll have to ignore the first element, blocktype[0], and leave room for blocktype[70], the 71st)
You can now assign elements like this:
blocktype[number] = 3;
and use them like so:
alert( blocktype[number] );

creating variable names from parameters in javascript

I was wondering if it is possible to create variable names from parameters passed to a function in javascript. Something like this:
function createVar(number) {
var "number" + number;
}
createVar(1)
I'm new to Stack Overflow and programming, so any help would be appreciated.
You could attach this to the window object, but note it will be global. For example:
function createVar(varName, value) {
window[varName] = value;
}
createVar("test", "Hello World");
alert(test); // Outputs "Hello World".
It is possible to interpret Object as associative array where you specify index and get value by name of index ( hash ):
var x = Array();
x[number] = value;
Single variable name is for programmer, and the code would be hard to maintain and understand when you set variable dynamically in code.
Honestly, I don't see why this would ever be useful, because every time you want to use the variable you'd have to search for it with your number argument.
However, you can do it, albeit not the exact way you had described:
function createVar(number){
eval("var number" + number.toString() + ";");
}
however, this variable will only be accessible within the function, to make it global assign to the window object:
function createVar(number){
window["number" + number] = 15; // creates "global" variable
}
As I've stated before, however, I don't see this being useful, [i]ever[/i], if you want to stratify values by numbers you'd be much better off with an array.

Declarating a variables with for operator in Javascript

I got an 2x10 array and I need set a variable to any member of that array. Make it by hands its not cool, so Im trying to declarate by for operator:
allImages=[
[
'img1-1','img1-2', 'img1-3', 'img1-4', 'img1-5'
],[
'img2-1','img2-2', 'img2-3', 'img2-4', 'img2-5'
]
];
for(i=0;i<1;i++){
console.log(i + ' part ------------------------');
for(j=0;j<5;j++){
x+(i+'-'+j) = allImages[i][j];
console.log((x+(i+'-'+j)) + '-> item');
}
}
But looks like I make a primitive error:
Invalid left-hand side in assignment
Anyway, I cant figure out how to solve this. Can anyone say how to declarate a lot of variables with custom keys throw for operator or with another method?
----- My solution by(https://stackoverflow.com/users/1230836/elias-van-ootegem):
var statImg = {};
var blurImg ={};
for (var i = 0; i < 13; i++) {
var keyName = 'img'+i;
var valOfKey = 'img/'+i+'.png'
statImg[keyName] = valOfKey;
blurImg[keyName] = valOfKey;
};
You'll have to either create an object, and use the left-hand trickery you're trying to generate property names, or you'll have to fall back to the global object (which I hope you don't):
var names = {};//create object
//-> in loop:
names[ x+(i+'-'+j)] = allImages[i][j];
To be complete, but again: don't actually go and do this, you could replace names with window. In which case, you'll be polluting the global scope.
Perhaps you might want to check the values (like x, i and j) for values that make it "difficult" to access the properties, like %, or indeed the dash you're concatenating in your example:
var anObj = {};
anObj['my-property'] = 'this is valid';
console.log(anObj.my-property);//ReferenceError: property is not defined
That is because the dash, or decrement operator isn't seen as part of the property. Eitherway, using separate variables is, in your case, not the best way to go. Programming languages support arrays and objects because of this very reason: grouping related data, making them easy to access through a single variable.
If needs must, just use an object, if not, construct an array you sort using array.sort(function(){});
check MDN on how to acchieve this, if you're stuck down the way, let us know....

How to add index to constructed object?

On (document).ready im would like to dynamically generate elements inside a certain parent-element. Lets call them "Candles".
Each "Candle" needs different properties for backgroundImage and color depending on their index().
After creating the page, these attributes need to be changeable via the interface. So its important to save the properties of the "candles" independent from each other.
Thats why I thought it might be useful, to generate for an object for each "Candle" to save their individual properties and to make them editable.
var candleAmount = 3;
for (var i=1; i <= candleAmount; i++) {
$("#container #candles").append("<li><img src=''></img></li>");
var Candle+i = [ "background":"+i+", "color":" - random - (ignore)" ]
};
(please dont mind any failures in the code besides the "Candle+i", I'll figure it out.)
EDIT: Ok, thank you so far. I might not made myself clear enaugh.
Here is an way more reduced example:
$("ul#candles li").each( function(i) {
candle+i = i+" Anything";
});
alert(candle4);
I would love to create an amount of variables depending on the Amount of child-objects.
What would be the correct syntax, or isn't there any?
Thank you
just put them in an array and access them via index. Result is most likely the same for you and is much better than let them floating in your scope
So is there any way, to generate object-names with an index?
Yes, in JavaScript, global variables are defined as properties of the global-object. (Inside a function, variables are defined as properties of the Activation object.) You can reference the global object by window (for browser applications) or just by this.
And because all objects are associative you can give there properties just the name you want. So, setting a global variable is equal to set a property into the global object.
var foo = "bar"; === this["foo"] = "bar";
Now, its just a small step to add a dynamic part to the name:
for(var i=0;i<10;i++) {
this['candle' + i] = i;
}
alert(candle7);
For your specific code:
$("ul#candles li").each( function(i) {
window["candle" + i] = i+" Anything";
});
alert(candle4);

Categories