How to increase function by 1 using loop in javascript - javascript

I want to run a loop that auto increase the function name by 1. For easier to understand:
My currently code:
for(var i = 1; i <= 2; i++) {
var fn = 'this.getExterior',
el = (fn + i + '()').getInnerItems();
}
I want to increase the function name and retrieve something like this.getExterior1 , this.getExterior2. The above code give me an object not a function. Can someone give me a solution how to achieve it. Thank you very much in advance!

You can't really use strings as code (eval can but it's not necessary here). You can use the [] syntax:
el = this["getExterior" + i]().getInnerItems();
(Also, function is a keyword; you cannot use it as a variable name.)

it will be :
var el = this['getExterior'+i]().getInnerItems();
in javascript any property or object can be accessed this way
object.property is the same as object['property']

Something like the following:
var i, fn;
for (i = 1; i <= 2; ++i) {
fn = 'getExterior' + i;
el = this[fn]().getInnerItems();
}

Related

Each() issue in vanilla javascript

Everytime I try to reproduce .each() jQuery function in vanilla JavaScript, I'm in trouble.
When I try to change this :
$("[data-lng]").each(function(){
var lng = $(this).data('lng');
$('#language').text(lng)
});
To this :
var elem = document.querySelectorAll("[data-lng]");
Array.prototype.forEach.call(elem, function(){
document.getElementById('language').write = elem.dataset.lng
});
Console returns elem.dataset is not defined
Plus, I'm dealing with data stuff so I'm not even sure if its legal to write this document.querySelectorAll("[data-lng]")
Thanks for your help !
PS : Here is an example of what I want to convert into vanilla JS :
https://jsfiddle.net/x93oLad8/4/
Its fairly trivial to swap your jsFiddle example out for vanilla JS. One 'gotcha' to be aware of is that IE has no support for NodeList.prototype.forEach() hence using a regular for loop instead. (See: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach)
var dictionary = {
'greet': {
'it': 'Ciao',
'en': 'Hello',
'fr': 'Salut',
}
};
var langs = ['it', 'en', 'fr'];
var current_lang_index = 0;
var current_lang = langs[current_lang_index];
window.change_lang = function() {
current_lang_index = ++current_lang_index % 3;
current_lang = langs[current_lang_index];
translate();
}
function translate() {
/* jQuery:
$("[data-translate]").each(function(){
var key = $(this).data('translate');
$(this).html(dictionary[key][current_lang] || "N/A");
});*/
/* vanilla */
var dt = document.querySelectorAll("[data-translate]");
//iterate over the NodeList:
for (i = 0; i < dt.length; ++i) {
var key = dt[i].getAttribute('data-translate');//get the key
dt[i].innerHTML = (dictionary[key][current_lang] || "N/A");//set the text
}
}
translate();
<div data-translate="greet"></div>
<button onclick="change_lang()">Change Language</button>
First of all, instead of using:
Array.prototype.forEach.call(elem, function()
You can just use
elem.forEach(function()
Secondly, callback function can accept arguments (3 of them to be specific):
el - current elem (which is the "this" you are looking for? :))
index - index of current elem in array
list - the nodelist you loop over
Usage:
elem.forEach(function(el, index, list){
console.log(el); //logs current element
});
Read more: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach
#Edit: Since there was a big discussion in the comments about the first part, i feel obligated to link a thread on overriding default methods in JS: [].slice or Array.prototype.slice (a.k.a why elem.forEach might not work, just in case :))

Convert string value as variable name in js, like in php [duplicate]

I’ve looked for solutions, but couldn’t find any that work.
I have a variable called onlyVideo.
"onlyVideo" the string gets passed into a function. I want to set the variable onlyVideo inside the function as something. How can I do that?
(There are a number of variables that could be called into the function, so I need it to work dynamically, not hard coded if statements.)
Edit: There’s probably a better way of doing what you’re attempting to do. I asked this early on in my JavaScript adventure. Check out how JavaScript objects work.
A simple intro:
// create JavaScript object
var obj = { "key1": 1 };
// assign - set "key2" to 2
obj.key2 = 2;
// read values
obj.key1 === 1;
obj.key2 === 2;
// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;
// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;
If it's a global variable then window[variableName]
or in your case window["onlyVideo"] should do the trick.
Javascript has an eval() function for such occasions:
function (varString) {
var myVar = eval(varString);
// .....
}
Edit: Sorry, I think I skimmed the question too quickly. This will only get you the variable, to set it you need
function SetTo5(varString) {
var newValue = 5;
eval(varString + " = " + newValue);
}
or if using a string:
function SetToString(varString) {
var newValue = "string";
eval(varString + " = " + "'" + newValue + "'");
}
But I imagine there is a more appropriate way to accomplish what you're looking for? I don't think eval() is something you really want to use unless there's a great reason for it. eval()
As far as eval vs. global variable solutions...
I think there are advantages to each but this is really a false dichotomy.
If you are paranoid of the global namespace just create a temporary namespace & use the same technique.
var tempNamespace = {};
var myString = "myVarProperty";
tempNamespace[myString] = 5;
Pretty sure you could then access as tempNamespace.myVarProperty (now 5), avoiding using window for storage. (The string could also be put directly into the brackets)
var myString = "echoHello";
window[myString] = function() {
alert("Hello!");
}
echoHello();
Say no to the evil eval. Example here: https://jsfiddle.net/Shaz/WmA8t/
You can do like this
var name = "foo";
var value = "Hello foos";
eval("var "+name+" = '"+value+"';");
alert(foo);
You can access the window object as an associative array and set it that way
window["onlyVideo"] = "TEST";
document.write(onlyVideo);
The window['variableName'] method ONLY works if the variable is defined in the global scope. The correct answer is "Refactor". If you can provide an "Object" context then a possible general solution exists, but there are some variables which no global function could resolve based on the scope of the variable.
(function(){
var findMe = 'no way';
})();
If you're trying to access the property of an object, you have to start with the scope of window and go through each property of the object until you get to the one you want. Assuming that a.b.c has been defined somewhere else in the script, you can use the following:
var values = window;
var str = 'a.b.c'.values.split('.');
for(var i=0; i < str.length; i++)
values = values[str[i]];
This will work for getting the property of any object, no matter how deep it is.
It can be done like this
(function(X, Y) {
// X is the local name of the 'class'
// Doo is default value if param X is empty
var X = (typeof X == 'string') ? X: 'Doo';
var Y = (typeof Y == 'string') ? Y: 'doo';
// this refers to the local X defined above
this[X] = function(doo) {
// object variable
this.doo = doo || 'doo it';
}
// prototypal inheritance for methods
// defined by another
this[X].prototype[Y] = function() {
return this.doo || 'doo';
};
// make X global
window[X] = this[X];
}('Dooa', 'dooa')); // give the names here
// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());
The following code makes it easy to refer to each of your DIVs and other HTML elements in JavaScript. This code should be included just before the tag, so that all of the HTML elements have been seen. It should be followed by your JavaScript code.
// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
{
thisid = els[i].id;
if (!thisid)
continue;
val=D.getElementById(thisid);
id[thisid]=val;
}
// Usage:
id.MyDIV.innerHTML="hello";
let me make it more clear
function changeStringToVariable(variable, value){
window[variable]=value
}
changeStringToVariable("name", "john doe");
console.log(name);
//this outputs: john doe
let file="newFile";
changeStringToVariable(file, "text file");
console.log(newFile);
//this outputs: text file

How can I loop over element ids in an array and assign them to variables?

I'm trying to refactor my window.onload function so as to avoid redundancy. I'd like to loop over the elements I'm assigning to global variables, using their ids. Initially, I was able to assign onclick functions with a loop, but now I'm not able to reproduce this in a fiddle. But the main issue is simply trying to do this (see fiddle):
var gragh, gorgh;
var ids = ["gragh", "gorgh"];
for (var i = 0; i < ids.length; i++) {
ids[i] = document.getElementById(ids[i]);
// TypeError: document.getElementById(ids[i]).onclick = doStuff;
}
//console.log(gragh); undefined
This is supposed to assign the variables gragh and gorgh to p elements which have the same ids. Within the loop, ids[i] seems to refer to the p elements. After the loop, however, these variables are undefined. This also doesn't work when looping through an array with these variables not surrounded by quotes. I've even tried using eval(), with mixed results. So my question is, how can I get this to work? And also, why doesn't this work? If ids = [gragh, gorgh] (without the quotes), what do these variables within the array refer to?
Don't reassign it in your loop, try using a new array to populate. Think of it as a reference - you're modifying it while looping.
var gragh, gorgh;
var ids = ["gragh", "gorgh"];
var newSet = [];
for (var i = 0; i < ids.length; i++) {
newSet[i] = document.getElementById(ids[i]);
}
Loop will finish it's looping much before this onclick executes.So at that time the value of i will be the upper limit of the loop.
A work around of this a closure
var gragh;
var ids = ["gragh", "gorgh"];
for (var i=0; i<ids.length; i++) {
(function(i){ // creating closure
console.log(i)
document.getElementById(ids[i]).onclick = doStuff
})(i) // passing value of i
}
document.getElementById("gragh").innerHTML = "ids[0]: " + ids[0] + ", ids[1]: " + ids[1]
function doStuff() {
document.getElementById("gorgh").innerHTML = "ids[0]: " + ids[0] + ",ids[1]: " + ids[1] + ", var gragh: " + gragh;
}
gragh is undefined since you haveonly declared it but never initialized it
JSFIDDLE

Is it possible to assign a variable with a function? [duplicate]

I’ve looked for solutions, but couldn’t find any that work.
I have a variable called onlyVideo.
"onlyVideo" the string gets passed into a function. I want to set the variable onlyVideo inside the function as something. How can I do that?
(There are a number of variables that could be called into the function, so I need it to work dynamically, not hard coded if statements.)
Edit: There’s probably a better way of doing what you’re attempting to do. I asked this early on in my JavaScript adventure. Check out how JavaScript objects work.
A simple intro:
// create JavaScript object
var obj = { "key1": 1 };
// assign - set "key2" to 2
obj.key2 = 2;
// read values
obj.key1 === 1;
obj.key2 === 2;
// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;
// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;
If it's a global variable then window[variableName]
or in your case window["onlyVideo"] should do the trick.
Javascript has an eval() function for such occasions:
function (varString) {
var myVar = eval(varString);
// .....
}
Edit: Sorry, I think I skimmed the question too quickly. This will only get you the variable, to set it you need
function SetTo5(varString) {
var newValue = 5;
eval(varString + " = " + newValue);
}
or if using a string:
function SetToString(varString) {
var newValue = "string";
eval(varString + " = " + "'" + newValue + "'");
}
But I imagine there is a more appropriate way to accomplish what you're looking for? I don't think eval() is something you really want to use unless there's a great reason for it. eval()
As far as eval vs. global variable solutions...
I think there are advantages to each but this is really a false dichotomy.
If you are paranoid of the global namespace just create a temporary namespace & use the same technique.
var tempNamespace = {};
var myString = "myVarProperty";
tempNamespace[myString] = 5;
Pretty sure you could then access as tempNamespace.myVarProperty (now 5), avoiding using window for storage. (The string could also be put directly into the brackets)
var myString = "echoHello";
window[myString] = function() {
alert("Hello!");
}
echoHello();
Say no to the evil eval. Example here: https://jsfiddle.net/Shaz/WmA8t/
You can do like this
var name = "foo";
var value = "Hello foos";
eval("var "+name+" = '"+value+"';");
alert(foo);
You can access the window object as an associative array and set it that way
window["onlyVideo"] = "TEST";
document.write(onlyVideo);
The window['variableName'] method ONLY works if the variable is defined in the global scope. The correct answer is "Refactor". If you can provide an "Object" context then a possible general solution exists, but there are some variables which no global function could resolve based on the scope of the variable.
(function(){
var findMe = 'no way';
})();
If you're trying to access the property of an object, you have to start with the scope of window and go through each property of the object until you get to the one you want. Assuming that a.b.c has been defined somewhere else in the script, you can use the following:
var values = window;
var str = 'a.b.c'.values.split('.');
for(var i=0; i < str.length; i++)
values = values[str[i]];
This will work for getting the property of any object, no matter how deep it is.
It can be done like this
(function(X, Y) {
// X is the local name of the 'class'
// Doo is default value if param X is empty
var X = (typeof X == 'string') ? X: 'Doo';
var Y = (typeof Y == 'string') ? Y: 'doo';
// this refers to the local X defined above
this[X] = function(doo) {
// object variable
this.doo = doo || 'doo it';
}
// prototypal inheritance for methods
// defined by another
this[X].prototype[Y] = function() {
return this.doo || 'doo';
};
// make X global
window[X] = this[X];
}('Dooa', 'dooa')); // give the names here
// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());
The following code makes it easy to refer to each of your DIVs and other HTML elements in JavaScript. This code should be included just before the tag, so that all of the HTML elements have been seen. It should be followed by your JavaScript code.
// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
{
thisid = els[i].id;
if (!thisid)
continue;
val=D.getElementById(thisid);
id[thisid]=val;
}
// Usage:
id.MyDIV.innerHTML="hello";
let me make it more clear
function changeStringToVariable(variable, value){
window[variable]=value
}
changeStringToVariable("name", "john doe");
console.log(name);
//this outputs: john doe
let file="newFile";
changeStringToVariable(file, "text file");
console.log(newFile);
//this outputs: text file

Trying to avoid eval getting array element from window object

I've got a function that wants to access a global variable, the name of which arrives as a string argument. This is how it looks now, using eval:
function echoVar(whichone){
document.write(eval(whichone));
}
I thought I'd just use the window[] syntax and have this:
function echoVar(whichone) {
document.write(window[whichone]);
}
If I create a var and call it like this, it doc writes ABC as expected:
var abc = "ABC";
echoVar("abc");
If the var I want to access is an array element though, it doesn't work:
var def = ["DEF"];
echoVar("def[0]"); //fails with undefined
Obviously that's actually executing window[def[0]] which rightly gives undefined (because there's no variable called DEF). What I actually want to happen is that it executes window["def"][0].
The only way I know to achieve this, is to do a split on the whichone parameter with "[" as the delimiter and then use the split [0] as the window index and a parseInt on split [1] to get the index, like this:
function echoVar(whichone){
if(whichone.indexOf("[")==-1){
document.write(window[whichone]);
}
else{
var s = whichone.split("[");
var nam = s[0];
var idx = parseInt(s[1]);
document.write( window[nam][idx] );
}
}
Am I overlooking something obvious? I'd rather keep the eval than have to do all that.
If you dislike using eval in your code, you can always do this:
function echoVar(whichone) {
document.write(Function("return " + whichone)());
}
Unless this is some sick experiment, you should never be writing Javascript code that looks like this. This is terrible; you need to re-think your design. I know this isn't what you're looking for, but it's the right answer.
The fact is you've got a piece of a javscript expression in a string so you either have to parse it yourself or use eval to parse it for you unless you change the way it's passed like this:
function echoVar(a,b) {
var x = window[a];
if (b) {
x = x[b];
}
document.write(x);
}
And, then you can pass it differently like this:
var def = ["DEF"];
echoVar("def", 0); // def[0]
You could even make this support multiple dimensions if you needed to.
function echoVar(a) {
var x = window[a];
for (var i = 1; i < arguments.length; i++) {
x = x[arguments[i]];
}
document.write(x);
}
var def = {myObject: {length: 3}}
echoVar("def", "myObject", "length"); // def["myObject"]["length"] or def.myObject.length
You can see it work here: http://jsfiddle.net/jfriend00/dANwq/
It would be simpler to lose the brackets and call the item with dot notation
function reval(s, O){
s= String(s);
O= O || window;
var N= s.split(".");
while(O && N.length) O= O[N.shift()];
return O || s;
}
window.def= ['definition'];
alert(reval('def.0'))
/* returned value: (String)
definition
*/

Categories

Resources