I want to know if there exists a tool to help in reversing a compressed javascript that has obscure variable names. I am not looking for a pretty-printing beautifier, but for a tool that actually knows how to change & propagate variable name choices.
Let me be more specific :
- some of the functions belong to the 'public' API and i want to impose readable argument names in their prototypes
- there are intermediary variables for document, window and other browser idioms
I would like to give this knowledge to the tool and then let it create another javascript where the knowledge would have been correctly propagated.
thanks
Jerome Wagner
Sounds like maybe you need a javascript refactoring tool. Something that could refactor javascript, i.e take a javascript file and rename variables.
Here are some plugins for IDE's:
http://www.brics.dk/jsrefactor/index.html
http://www.jetbrains.com/editors/javascript_editor.jsp?ide=idea#JavaScript%5Frefactoring
If you are trying to do this programatically, then this may not be the best solution for you.
Related
I have to use this.state.<name> multiple times, how should I replace it with a simple variable name? Like we use global variables in other languages such as C, C++.
#Thomas yes, but there are a lot of functions in my code and even many items inside state for which i want shorter alias. So it is not ideal to do it with "const" in all functions. so by the word "globally", i meant how to declare those shorter alias only once ?
you can't. Javascript simply doesn't provide that feature.
JavaScript as a Language doesn't have the compile-step where these aliases would be filled in with the real commands.
There are preprocessors, like babel for wich you could write a plugin.
There are task-runner like gulp for wich you could write a script to build that aliasing syntax (although it's most likely not valid JS)
You can check out sweet.js maybe its functionalities already get you covered.
But maybe you'd consider learning JavaScript; realizing that JavaScript is not C and that you can't just transfer your coding style 1:1.
imo. the best Solution to get a bunch of shorter handles is Object destructuring. But this ain't aliases either; you need to understand what JS does here, and what the limits to this are.
Don't be too lazy to write a few more characters. Every modern JS IDE has an autocompletiton feature.
You can so something like this in render.
const { name } = this.state;
return(
<div>{name}</div>
)
Now you can use it just with name as many times you want in render as well you can do in methods.
It is not like creating alias but we can optimize code.
Let's say you would get a bunch of .js files and now it is your job to sort them into groups like:
requires at least JavaScript 1.85
requires at least E4X (ECMAScript 4 EX)
requires at least ECMAScript 5
or something like this.
I am interested in any solution, but especially in those which work using JavaScript or PHP. This is used for creation of automated specifications, but it shouldn't matter - this is a nice task which should be easy to solve - however, I have no idea how and it is not easy for me. So, if this is easy to you, please share any hints.
I would expect something like this - http://kangax.github.com/es5-compat-table/# - just not for browsers, rather for a given file to be checked against different implementations of JavaScript.
My guess is, that each version must have some specifics, which can be tested for. However, all I can find is stuff about "what version does this browser support".
PS: Don't take "now it is your job" literally, I used it to demonstrate the task, not to imply that I expect work done for me; while in the progress of solving this, it would be just nice to have some help or direction.
EDIT: I took the easy way out, by recquiring ECMAScript 5 to be supported at least as good as by the current FireFox for my projekt to work as intendet and expected.
However, I am still intereseted in any solution-attemps or at least an definite answer of "is possible(, with XY)" or "is not possible, because ..."; XY can be just some Keyword, like FrameworkXY or DesignPatternXY or whatever or a more detailed solution of course.
Essentially you are looking to find the minimum requirements for some javascript file. I'd say that isn't possible until run time. JavaScript is a dynamic language. As such you don't have compile time errors. As a result, you can't tell until you are within some closure that something doesn't work, and even then it would be misleading. Your dependencies could in fact fix many compatibility issues.
Example:
JS File A uses some ES5 feature
JS File B provides a shim for ES5 deficient browsers or at least mimics it in some way.
JS File A and B are always loaded together, but independently A looks like it won't work.
Example2:
Object.create is what you want to test
Some guy named Crockford adds create to Object.prototype
Object.create now works in less compatible browsers, and nothing is broken.
Solution 1:
Build or find a dependency map. You definitely already have a dependency map, either explicitly or you could generate it by iterating over you HTML files.
Run all relevant code paths in environments with decreasing functionality (eg: ES5, then E4X, then JS 1.x, and so forth).
Once a bundle of JS files fail for some code path you know their minimum requirement.
Perhaps you could iterate over the public functions in your objects and use dependency injection to fill in constructors and methods. This sounds really hard though.
Solution 2:
Use webdriver to visit your pages in various environments.
Map window.onerror to a function that tells you if your current page broke while performing some actions.
On error you will know that there is a problem with the bundle on the current page so save that data.
Both these solutions assume that you always write perfect JS that never has errors, which is something you should strive for but isn't realistic. This might; however, provide you with some basic "smoke testing" though.
This is not possible in an exact way, and it also is not a great way of looking at things for this type of issue.
Why its not possible
Javascript doesn't have static typing. But properties are determined by the prototype chain. This means that for any piece of code you would have to infer the type of an object and check along the prototype chain before determining what function would be called for a function call.
You would for instance, have to be able to tell that $(x).bind() o $(x).map are not making calls to the ecmascript5 map or bind functions, but the jQuery ones. This means that you would really have to parse out the whole code and make inferences on type. If you didn't have the whole code base this would be impossible. If you had a function that took an object and you called bind, you would have no idea if that was supposed to be Function.prototype.bind or jQuery.bind because thats not decided till runtime. In fact its possible (though not good coding practice) that it could be both, and that what is run depends on the input to a function, or even depends on user input. So you might be able to make a guess about this, but you couldn't do it exactly.
Making all of this even more impossible, the eval function combined with the ability to get user input or ajax data means that you don't even know what types some objects are or could be, even leaving aside the issue that eval could attempt to run code that meets any specification.
Here's an example of a piece of code that you couldn't parse
var userInput = $("#input").val();
var objectThatCouldBeAnything = eval(userInput);
object.map(function(x){
return !!x;
});
There's no way to tell if this code is parsing a jQuery object in the eval and running jQuery.map or producing an array and running Array.prototype.map. And thats the strength and weakness of a dynamically typed language like javascript. It provides tremendous flexibility, but limits what you can tell about the code before run time.
Why its not a good strategy
ECMAScript specifications are a standard, but in practice they are never implemented perfectly or consistently. Different environments implement different parts of the standard. Having a "ECMAScript5" piece of code does not guarantee that any particular browser will implement all of its properties perfectly. You really have to determine that on a property by property basis.
What you're much better off doing is finding a list of functions or properties that are used by the code. You can then compare that against the supported properties for a particular environment.
This is still a difficult to impossible problem for the reasons mentioned above, but its at least a useful one. And you could gain value doing this even using a loose approximation (assuming that bind actually is ecmascript5 unless its on a $() wrap. Thats not going to be perfect, but still might be useful).
Trying to figure out a standard thats implemented just isn't practical in terms of helping you decide whether to use it in a particular environment. Its much better to know what functions or properties its using so that you can compare that to the environment and add polyfills if necessary.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Return all of the functions that are defined in a Javascript file
OK so i have a JS file in which i have a number of JavaScript functions defined.Is there any way to parse out the name of all function in that particular JS file using JavaScript.Any guidance or link to achieve this will be appreciated
If you are not generating the js file dynamically, the easiest and safest option is to keep a hard-coded list of function names.
All other parsing methods are risky because
String parsing of the code is not safe, since you will have to cater
too many cases
There are options to get all global functions. But they are browser
dependent. like looping through all window objects for objects with typeof window[x] === 'function'
If it's just for development purposes then use an IDE. The IDE will depend on your environment. For example, you might you IntelliJ if your server side code is Java or Visual Studio's if you are a .NET shop.
If you really need to use javascript to dynamically go through the list of functions I suggest rethinking why you need to do it. If it turns out usefull you could namespace your functions and then just iterate over the namespace functions. See this answer for how to namespace https://stackoverflow.com/a/5947280/695461. Then iterate over the "public" functions.
Again, if it's just for development ease of use, use an IDE. They have whole teams of people writing parsers and syntax highlighters and structure diagrams for you.
Pardon me for giving you a confusing title on this problem.
I'm really confused and i don't know how to put it in other words.
So here is what I what to accomplish.
I am making a Custom Javascript Object to store data.
I have automated this process and inserted each instance of the object into an array.
I am making a loop statement to invoke the unique property value of each instance of the object.
When I want to use an expression, the property name of the object would be variable since i don't know which one it is.
Basically I need to incorporate a string value into the prototype expression.
e.g
document.getElementById('text').style."fontsize"=value;
since I cannot do this directly, i thought possibly I could use the eval function:
eval('document.getElementById("text").style.' + buttons[i].cssvalue + '="39px";');
but this still doesn't work.
Can this be fixed or ss there an alternative way to accomplish this?
If there are some unclear stuff, please point out and I will try to elaborate.
Thanks in advance.
In javascript you can access properties of an object using this notation:
document.getElementById('text').style["fontSize"] = value;
So your code might be:
document.getElementById('text').style[buttons[i].cssvalue] = "39px";
I don't know if this helps or not but I made a utility function which I published to npm which allows you to put in a class name / element along with the CSS properties you're looking at getting. This will then return a Javascript object with the CSS properties and their values within it.
You can find it here on Github and NPM:
GitHub: https://github.com/tjcafferkey/stylerjs
NPM: https://www.npmjs.com/package/stylerjs
First thought, look at a Javascript library or framework like JQuery or Dojo they probably have already solved the problem you are looking at. We use JQuery at work but I prefer Dojo's design but it is more targeted at large web applications.
Other than that Jakub's solution should work.
I was looking at an answer to an SO question today where the variable names are ua, rv, etc. And I thought, "Man, when will people learn to use full-size variable names, memory is not a problem any more" but then, it is Javascript so it has to come across the wire and perhaps long variable names even slow down interpretation.
Is using short variable names in Javascript premature optimization?
While I'm here, are there any libraries for Rails or PHP that will compress Javscript on the fly, so I can keep my Javascript with long names on the server?
The only reason to use short variable names in JS is to save bytes over the wire. However, developing like that is ridiculous. Do they write JS without whitespace, too? There are tools which optimize finished JS. Crockford's is one of the most popular (though it does not shorten variable names). I can't recall offhand one that does obfuscate/shorten variable names, but they do exist and it's not that hard to write one, either. Google Closure is a very impressive JavaScript compiler that turns this:
var myFunction = function(arg1, arg2) {
var foo = getValue(arg2);
for(var count = 0; count < arg1.length; count++) {
alert(foo);
}
};
into this:
function a(b,c){var d=e(c);for(var f=0;f<b.length;f++){alert(d)}}
Dont use short variable names for optimization, during development. That would severely decrease readability. Compress your JS/CSS files at compile/deploy time, using something like YUI Compressor.
People use short variable names in javascript purely to save on bandwidth. It does not affect execution speed of the javascript. And I don't know about rails or PHP libraries, but there are certainly tools out there that can compress your javascript files (by renaming variables to be shorter and removing unnecessary whitespace).
We have not any reason to use not readable code at development.
As the other answers, I think you have a lot of resources to save bandwith and make happy the user with a fast load of the page.
Check these articles:
close-look-into-include-javascript-compression
Production-Grade-JS
I normal development, most of these answers are correct. There is no reason to use non-descriptive variable names.
However, when writing answers and examples on SO, variables don't necessarily mean anything in particular. They're just there for demonstration purposes, and have no need for any semantic meaning.