Reverse-engineer a Javascript object?
I have a Javascript object that I want to pass in more parameters, but the documentation is non-existant. My only option seems to be to reverse engineer the Javascript object to see what parameters and values I can pass in.
For example, I want to see if there is a "zoom" parameter for 开发者_运维知识库the object and what values I can pass into the "mapType" parameter:
<script type="text/javascript" src="http://maps.google.com/maps?oe=utf-8&file=api&v=2&key=your-gmap-key"></script>
<script type="text/javascript" src="https://share.findmespot.com/spot-widget/js/SpotMain.js"></script>
<script type="text/javascript">
var widget = new Spot.Ui.LiveWidget({ renderTo: "spot-live-widget",
feeds: [ "0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB" ],
height: 400,
width: 500,
mapType: "physical"
});
</script>
<div id="spot-live-widget"/>
Any ideas on how to do that?
Well... you could look at the source...
Your code leads to https://share.findmespot.com/spot-widget/js/SpotMain.js
which leads to https://share.findmespot.com/spot-widget/js/Spot.js, which you unpack using http://jsbeautifier.org/ which shows you that no, it cannot take a 'zoom' parameter in its constructor, but it does have a setZoomAndCenter
method
setZoomAndCenter: function (C) {
var B = new GLatLngBounds;
for (var A = 0; A < C.length; A++) {
B.extend(C[A].getPoint())
}
this._map.setZoom(this._map.getBoundsZoomLevel(B));
this._map.setCenter(B.getCenter())
},
And from this we can see that it has a 'private' member _map, which has a setZoom
method.
Does this help?
UPDATE
The above method was actually a member of Spot.Ui.MapRenderer
, not the LiveWidget.
The MapRenderer is used internally by LiveWidget but is not exposed...
Function#toString
Most Javascript implementations will return the source code of a function if you call the function instance's toString
method:
function foo() {
return a;
}
alert(foo.toString()); // Alerts "function foo() { return a; }"
This is non-standard behavior, but widely-supported; you may find it quite useful for reverse-engineering. Calling it on the Spot.Ui.LiveWidget
function may be interesting, as well as on functions bound to the properties of the object it returns. Which brings us to...
Edit Of course, if unobfuscated source is available (shout out to Sean), you don't need this...
Looping through Properties: for..in
If it's really a Javascript object, you can do this to find out what properties it has:
var name, own;
for (name in obj) {
own = obj.hasOwnProperty(name);
alert(name + " (" + (own ? "own" : "inherited") + ")");
}
That will tell you the names of its (enumerable) properties and whether those are properties of the instance itself, or its prototype object.
for..in
Example
function Thingy() {
}
Thingy.prototype.alpha = "a";
var t = new Thingy();
t.beta = "2";
The loop above would show:
alpha (inherited) beta (own)
(In no particular order.)
Further Information
Enumerable vs. Non-Enumerable properties
Note that not all properties are "enumerable". For instance, all (or nearly all) of the properties specified by the spec on objects like Array
, String
, etc. are non-enumerable. But until recently that was just something that could be done by the Javascript implementation itself; there was no mechanism for marking your own properties as being non-enumerable. The new 5th edition spec provides a means of doing that, but it isn't widely supported or used (yet).
Non-Existent Properties
The object you're querying may change its behavior based on whether a property is present or not; in that situation, you'd have no way of knowing, since a non-existent property doesn't show up in the for..in
loop (unlike a property that exists but has an undefined
value, which does). E.g.:
function doSomething(options) {
if (options.foo) {
// There's a `foo` and it has a value; do something with it
}
The foo
property may not exist at all on options
, so this reverse-engineering wouldn't reveal that the code did something with it.
Warning
Do not try the for..in
loop above on host objects, such as DOM nodes. It may work in some implementations, but usually not, and in some cases (IE6) it'll crash the browser. It's totally safe for Javascript objects, though.
There is no guarantee that the properties listed in a configuration parameter will match those of the resulting object, or that they will be copied to the resulting object even if they are.
The only way to find out is to look at the code in the LiveWidget "constructor" function, and see what properties it expects from the configuration parameter.
精彩评论