How know variable name in javascript? - javascript

Suposse an function:
function get(){}
this will get an variable
var name = "Eduardo";
get(name);
function get(n) {}
And i want to show the name of the variable that was passed, without know this name.
function get(n) {
return getNameVariableFromValue(n); // Pseudocode for explain my question
}
so, i want the name of variable without previouslu knowing this name.
PD: My question is mainly to know, who is a variable in the window object, without know this name or value

Your question assumes that no two properties would ever have the same value, which is highly unlikely. But, making that wild assumption, you'd need to make the new window property explicitly rather than just declare a global variable and then you could use Object.keys() to enumerate all the key names of the window object, looking for the one that matches your value. When found, report the key name.
window.myGlobal = "Test";
Object.keys(window).forEach(function(key){
if(window[key] === "Test"){
console.log(key);
}
});
This code won't work in the Stack Overflow snippet environment due to sandboxing, but you can see it working here (make sure to have your developer's tools console open when running).

You can send the value as an object to the function and do something like below
function get(n) {
return Object.keys(n)[0];
}
var name ="Test1";
var name2 = "Test2"
console.log(get({name}))
console.log(get({name2}))

Related

Function parameter: Get name of undefined variable

If one of my functions get an undefined parameter passed, I want to get the name of the variable outside the function so I can better troubleshoot the undefined variables. I.e.:
var myVar = document.getElementById("myTable").dataset.tablename;
//myVar: undefined
testVar(myVar);
testVar(param1) {
if (!param1) console.log(passed parameter ??? undefined);
}
//??? shall be "myVar"
I don't think the thing you want to achieve is possible. You can look at the stack trace at debug time, but I will give you further information and ideas here:
You could have a development policy in your team to name outside variables the same way as the parameters are at functions whenever possible. If you do so, this post will become useful.
You might introduce a policy to pass objects to functions, like {name: 'John', age: 3} and then you will know the keys.
You could create a Trackable prototype which would have a key and a value, like this:
function Trackable(name, value) {
this.name = name;
this.value = value;
}
and pass trackables to functions when their names will be needed, thus you will call testVar(new Trackable('myVar', myVar)) and inside you will check param1.value against undefined and if it is undefined, then use the name in your report.

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.

getting the name of a variable through an anonymous function

Is it possible to find the name of an anonymous function?
e.g. trying to find a way to alert either anonyFu or findMe in this code http://jsfiddle.net/L5F5N/1/
function namedFu(){
alert(arguments.callee);
alert(arguments.callee.name);
alert(arguments.callee.caller);
alert(arguments.caller);
alert(arguments.name);
}
var anonyFu = function() {
alert(arguments.callee);
alert(arguments.callee.name);
alert(arguments.callee.caller);
alert(arguments.caller);
alert(arguments.name);
}
var findMe= function(){
namedFu();
anonyFu();
}
findMe();
This is for some internal testing, so it doesn't need to be cross-browser. In fact, I'd be happy even if I had to install a plugin.
You can identify any property of a function from inside it, programmatically, even an unnamed anonymous function, by using arguments.callee. So you can identify the function with this simple trick:
Whenever you're making a function, assign it some property that you can use to identify it later.
For example, always make a property called id:
var fubar = function() {
this.id = "fubar";
//the stuff the function normally does, here
console.log(arguments.callee.id);
}
arguments.callee is the function, itself, so any property of that function can be accessed like id above, even one you assign yourself.
Callee is officially deprecated, but still works in almost all browsers, and there are certain circumstances in which there is still no substitute. You just can't use it in "strict mode".
You can alternatively, of course, name the anonymous function, like:
var fubar = function foobar() {
//the stuff the function normally does, here
console.log(arguments.callee.name);
}
But that's less elegant, obviously, since you can't (in this case) name it fubar in both spots; I had to make the actual name foobar.
If all of your functions have comments describing them, you can even grab that, like this:
var fubar = function() {
/*
fubar is effed up beyond all recognition
this returns some value or other that is described here
*/
//the stuff the function normally does, here
console.log(arguments.callee.toString().substr(0, 128);
}
Note that you can also use argument.callee.caller to access the function that called the current function. This lets you access the name (or properties, like id or the comment in the text) of the function from outside of it.
The reason you would do this is that you want to find out what called the function in question. This is a likely reason for you to be wanting to find this info programmatically, in the first place.
So if one of the fubar() examples above called this following function:
var kludge = function() {
console.log(arguments.callee.caller.id); // return "fubar" with the first version above
console.log(arguments.callee.caller.name); // return "foobar" in the second version above
console.log(arguments.callee.caller.toString().substr(0, 128);
/* that last one would return the first 128 characters in the third example,
which would happen to include the name in the comment.
Obviously, this is to be used only in a desperate case,
as it doesn't give you a concise value you can count on using)
*/
}
Doubt it's possible the way you've got it. For starters, if you added a line
var referenceFu = anonyFu;
which of those names would you expect to be able to log? They're both just references.
However – assuming you have the ability to change the code – this is valid javascript:
var anonyFu = function notActuallyAnonymous() {
console.log(arguments.callee.name);
}
which would log "notActuallyAnonymous". So you could just add names to all the anonymous functions you're interested in checking, without breaking your code.
Not sure that's helpful, but it's all I got.
I will add that if you know in which object that function is then you can add code - to that object or generally to objects prototype - that will get a key name basing on value.
Object.prototype.getKeyByValue = function( value ) {
for( var prop in this ) {
if( this.hasOwnProperty( prop ) ) {
if( this[ prop ] === value )
return prop;
}
}
}
And then you can use
THAT.getKeyByValue(arguments.callee.caller);
Used this approach once for debugging with performance testing involved in project where most of functions are in one object.
Didn't want to name all functions nor double names in code by any other mean, needed to calculate time of each function running - so did this plus pushing times on stack on function start and popping on end.
Why? To add very little code to each function and same for each of them to make measurements and calls list on console. It's temporary ofc.
THAT._TT = [];
THAT._TS = function () {
THAT._TT.push(performance.now());
}
THAT._TE = function () {
var tt = performance.now() - THAT._TT.pop();
var txt = THAT.getKeyByValue(arguments.callee.caller);
console.log('['+tt+'] -> '+txt);
};
THAT.some_function = function (x,y,z) {
THAT._TS();
// ... normal function job
THAT._TE();
}
THAT.some_other_function = function (a,b,c) {
THAT._TS();
// ... normal function job
THAT._TE();
}
Not very useful but maybe it will help someone with similar problem in similar circumstances.
arguments.callee it's deprecated, as MDN states:
You should avoid using arguments.callee() and just give every function
(expression) a name.
In other words:
[1,2,3].forEach(function foo() {
// you can call `foo` here for recursion
})
If what you want is to have a name for an anonymous function assigned to a variable, let's say you're debugging your code and you want to track the name of this function, then you can just name it twice, this is a common pattern:
var foo = function foo() { ... }
Except the evaling case specified in the MDN docs, I can't think of any other case where you'd want to use arguments.callee.
No. By definition, an anonymous function has no name. Yet, if you wanted to ask for function expressions: Yes, you can name them.
And no, it is not possible to get the name of a variable (which references the function) during runtime.

JS Variable inside another variable

I have a function that would use other variables, depending on what has been passed.
Like this = ActionBar(slot) slot contains "one".
and I would like to create a call inside that like object.slot.name but it should convert it before hand to make the command look like object.one.name. Is there a way to do this in javascript/jquery?
I remember vaguely that some other language does this as {slot} or something like that.
Sorry if this question was already asked, I've checked google and stackoverflow too, but didn't find an answer.
Also I'd like to know what's the proper programming term for this kind of variable passing?
Edited it cause of misunderstandings. I'm looking into OOP js, so object is an object, one is an object, and name is an attribute, but when passing I'm passing "one" as a string to the function.
Tried eval, it doesn't work while dotted with an object.
Source code:
function disableActionButton(slot){
$("#"+slot).attr("disabled","disabled")
gcd = player.slot.gcd*1000
cd = setInterval(function(){
gcd = gcd - 10
$("#"+slot).val(gcd+"ms").css("color","red");
},10)
setTimeout(function(){
window.clearInterval(cd)
$("#"+slot).removeAttr("disabled").css("color","black").val(player.slot.name);
}, player.slot.gcd*1000)
}
It's really unclear what your current structure is (much clearer now you've posted code, see "update" below), but fundamentally the way to do this sort of thing in JavaScript is to have a container object. (If you don't already have one, introduce one.) Then slot can refer to a property of that object, like this:
var container = {
one: "This is one",
two: "This is two"
};
// ...
function foo(slot) {
console.log(container[slot]);
}
// ...
foo("one"); // ends up logging "This is one"
foo("two"); // ends up logging "This is two"
This works because the container object has properties, which in JavaScript can be referred to in two different ways:
Using dot notation and a literal name, e.g. container.one, or
Using bracketed notation and a name in a string, e.g. container["one"].
They're exactly equivalent except where the property name comes from. And of course, in the second case, the property name needn't be a literal string, it can be the result of any expression, including a variable reference (e.g., you can get the name from slot).
This works with all object properties, including properties that refer to functions. I mention this only because you mentioned functions in your question, so if you need to, you can do this:
function foo(slot) {
container[slot]();
}
...which calls the function on container that the property with the name held by the slot argument. So if slot is "one", it does container.one().
Update:
Your source directly echos the container example above, just apply the above to it:
function disableActionButton(slot){
$("#"+slot).attr("disabled","disabled")
// ---------v----v---- here
gcd = player[slot].gcd*1000
cd = setInterval(function(){
gcd = gcd - 10
$("#"+slot).val(gcd+"ms").css("color","red");
},10)
setTimeout(function(){
window.clearInterval(cd)
// ------------------------------------------------------------ and here--v----v
$("#"+slot).removeAttr("disabled").css("color","black").val(player[slot].name);
// ------v----v------- and here
}, player[slot].gcd*1000)
}
Or, rather than looking up the slot data each time, grab it once and reuse it:
function disableActionButton(slot){
// Grab it once...
var slotdata = player[slot];
$("#"+slot).attr("disabled","disabled")
// ---vvvvvvvvv--- then use it
gcd = slotdata.gcd*1000
cd = setInterval(function(){
gcd = gcd - 10
$("#"+slot).val(gcd+"ms").css("color","red");
},10)
setTimeout(function(){
window.clearInterval(cd)
$("#"+slot).removeAttr("disabled").css("color","black").val(slotdata.name);
}, slotdata.gcd*1000)
}
There's no special name for this. You're passing a property name into a function, and the function is looking up the property on the player object using that name. In some other languages this might be called "reflection" but the term doesn't really apply to dynamic languages like JavaScript.

Dynamic Javascript - Is This Valid?

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.

Categories