is there a way to find all variables with a specific value in JS?
I know there is a variable holding value integer 374646 but I can not find it in sources (large codebase).
I think one can implement a solution by recursively checking all variables returned by this but I am not a JS developer
update:
the original question was confusing I think.
is there any way that I can find variables by values in a browser debugger (Chrome/Firefox)?
I think one can implement a solution by recursively checking all variables returned by this but I am not a JS developer
No, you can't. Properties are not variables (except in one special case: a certain class of global variables are properties of the global object).
Unless your variable is a global, and it's the kind of global that's available as a property on the global object, you can't find it. There is no way to get a list of other kinds of variables.
For example, there is no way for code at global scope to find a in the following:
const handle = (() => {
const a = 374646;
return setInterval(() => {
console.log(a);
}, 500);
})();
setTimeout(() => clearInterval(handle), 4000);
Please note that it's dangerous and do not access the sites, that you don't know with that approach!!! All your data may get stolen, your girlfriend may get r#$%ped, your grandma may die, your dog may bite you in the crotch, all the glaciers in the world may melt, you can get herpes or even start a global nuclear war! Use at own risk! A very high risk if you don't know what running a browser without cross-domain policies means!
Run your browser with cross-domain policies disabled (for example Chromium / Chrome with --disable-web-security param, note : Kill all chrome instances before running command or it won't work), then in the console copy-paste this function:
function globalSearch(startObject, value) {
var stack = [[startObject,'']];
var searched = [];
var found = false;
var isArray = function(test) {
return Object.prototype.toString.call( test ) === '[object Array]';
}
while(stack.length) {
var fromStack = stack.pop();
var obj = fromStack[0];
var address = fromStack[1];
if( typeof obj == typeof value && obj == value) {
var found = address;
break;
}else if(typeof obj == "object" && searched.indexOf(obj) == -1){
if ( isArray(obj) ) {
var prefix = '[';
var postfix = ']';
}else {
var prefix = '.';
var postfix = '';
}
for( i in obj ) {
stack.push( [ obj[i], address + prefix + i + postfix ] );
}
searched.push(obj);
}
}
return found == '' ? true : found;
}
After that you can search variable by values with:
globalSearch(window,value);
Once again! Remember that it's dangerous and do not access the sites, that you don't know with that approach!!! Disclaimer: If something will happen, you didn't even see that post, I didn't write it! I don't know what StackOverflow is! Never been here.
Related
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
I have a JSON object which I get from a server. The key which I get the value from looks something like this:
var myJson = data.body.region.store.customer.name;
I am trying to get the name key here, but sometimes the JSON (which comes from a service I have no control over) will have some empty fields, like for instance name might not be defined so the object will actually look like this: data.body.region.store.customer. Sometimes too customer, or store, or region might not be defined (If the data doesn't exist the service doesn't return a null or empty string for the value).
So if I need the name what I am doing is this:
if(data.body.region.store.customer.name){
//Do something with the name
}
But say even store isn't defined, it will not get the value for name(which I would expect to be undefined since it doesn't exist) and the program crashes. So what I am doing now is checking every part of the JSON before I get the value with AND operands:
if(data && data.body && data.body.region && data.body.region.store && data.body.region.store.customer && data.body.region.store.customer.name){
//Do something with the name value then
}
This works, because it checks sequentially, so it first checks does data exist and if it does it checks next if data.body exists and so on. This is a lot of conditions to check every time, especially since I use the service a lot for many other things and they need their own conditions too. So to just check if the name exists I need to execute 6 conditions which of course doesn't seem very good performance wise (and overall coding wise). I was wondering if there is a simpler way to do this?
var myJson = null;
try {
myJson = data.body.region.store.customer.name;
}
catch(err) {
//display error message
}
You can try following
function test(obj, prop) {
var parts = prop.split('.');
for(var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
if(obj !== null && typeof obj === "object" && part in obj) {
obj = obj[part];
}
else {
return false;
}
}
return true;
}
test(myJson, 'data.body.region.store.customer.name');
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
My goal: Test if the attribute of an object is/returns true. However, in some cases, the object is undefined.
This works no problem. The script continues normally.
if(somethingUndefined){ }
However, if I try to access an attribute of an undefined object, this generates an error and stops the script.
if(somethingUndefined.anAttribute){ }
Right now, this is what I'm using to solve the problem:
if(somethingUndefined && somethingUndefined.anAttribute){ }
Is there another way to do that? Maybe a global settings that will return false if the program tries to access an attribute of an undefined object?
If you have many if statement like if(somethingUndefined && somethingUndefined.anAttribute){ }, then you could assign an empty object to it when it is undefined.
var somethingUndefined = somethingUndefined || {};
if (somethingUndefined.anAttribute) {
}
You can take advantage of JavaScript's ability to assign variables within if conditions and follow this pattern for faster checks once you get past the first nested object.
JsPerf
var x;
if(
(x = somethingUndefined) && // somethingUndefined exists?
(x = x.anAttribute) && // x and anAttribute exists?
(x = x.subAttrubute) // x and subAttrubute exists?
){
}
vs the traditional
if(
somethingUndefined && // somethingUndefined exists?
somethingUndefined.anAttribute && // somethingUndefined and anAttribute exists?
somethingUndefined.anAttribute.subAttribute // somethingUndefined and anAttribute and subAttribute exists?
){
}
The way you have it in your question is generally the way it's done in javascript. If you find yourself using this a lot, you could abstract it out into a function to make things a tiny bit cleaner for yourself, as such:
if (attrDefined(obj, 'property')) {
console.log('it is defined, whoo!');
}
function attrDefined(o, p){ return !!(o && o[p]) }
trying to determine a decent, cross browser method for obtaining attributes with javascript? assume javascript library use (jQuery/Mootools/etc.) is not an option.
I've tried the following, but I frequently get "attributes" is null or not an object error when IE tries to use the "else" method. Can anyone assist?
<script type="text/javascript">
//...
getAttr: function(ele, attr) {
if (typeof ele.attributes[attr] == 'undefined'){
return ele.getAttribute(attr);
} else {
return ele.attributes[attr].nodeValue;
}
},
//...
</script>
<div>
Link
</div>
using the above html, in each browser, how do I getAttr(ele, 'href')? (assume selecting the ele node isn't an issue)
For the vast majority of cases you can simply use the built in getAttribute function.
e.g.
ele.getAttribute(attr)
According to QuirksMode this should work on all major browsers (IE >= 6 included), with a minor exception:
In IE5-7, accessing the style attribute gives an object, and accessing the onclick attribute gives an anonymous function wrapped around the actual content.
With regard to your question's update, you could try this.
It may be overkill, but if getAttribute() and the dot notation don't return a result, it iterates through the attributes object to try to find a match.
Example: http://jsfiddle.net/4ZwNs/
var funcs = {
getAttr: function(ele, attr) {
var result = (ele.getAttribute && ele.getAttribute(attr)) || null;
if( !result ) {
var attrs = ele.attributes;
var length = attrs.length;
for(var i = 0; i < length; i++)
if(attrs[i].nodeName === attr)
result = attrs[i].nodeValue;
}
return result;
}
};
var result = funcs.getAttr(el, 'hash');
It's up to you to do some cross-browser testing, though. :o)
Using ele.attributes, you need to access them by index, as in:
ele.attributes[0].nodeName; // "id" (for example)
ele.attributes[0].nodeValue; // "my_id" (for example)
Trying to pass attributes an attribute name appears to return a value whose typeof is object, so your else code is running even though ele.attributes[attr] doesn't give you the value you want.
You are trying to access properties of ele before you've established if those properties exist. Try this kind of evidence chain:
if (ele.attributes && ele.attributes[attr] && typeof ele.attributes[attr] == 'undefined')
etc.