Javascript, as a dynamic language, has many methods to dynamically parse scripts, such as Eval, a low-key function, and execScript exclusively exclusive to IE, and the text attribute of the script tag on the DOM side, w3C script labels can also be parsed by directly adding text nodes or innerhtml scripts. With these methods, private attributes are nowhere to hide. Previously, FF's eval was more evil. If it was a function constructed in the module mode, it would be easy to get its private variables. However, the bug has been upgraded, so I won't talk about it.
The principle is that the function in the inner scope can access the variable in the outer scope at will. For this reason, we need to design an internal function to "input" the internal function, but it is not good to directly modify the original function. We can copy a copy, but obviously we do not need to receive all the orders, as long as a part of it can be done. How do I only need a part? All functions have a property called tostring. We use it for transformation and add it to our internal function, and then use dynamic parsing to restore it.
VaR reveal = function (FN, T) {// Private variable used to obtain the target function // var get = function (t) exists as the internal function of the new function) {return eval (t) ;}; // obtain the original function body var body = fn. tostring (). match (/function. +? \ {([\ S] *) \}/) [1]; // a new function with a parameter, returns the private variable VAR newfn = function ('A', 'var get = '+ Get +' \ n' + body + "\ n; return get (A) of the target function) "); Return newfn (t); // execute the new function}
Usage:
VaR parent = function () {var P = 'private variable ';}; var pp = Dom. Reveal (parent, 'P'); alert (PP) // Private variable!
<Br/> var reveal = function (FN, T) {<br/> // Private variable used to obtain the target function <br/> // exists as the internal function of the new function <br/> var get = function (t) {return eval (t) ;}; <br/> // obtain the original function body <br/> var body = fn. tostring (). match (/function. +? \ {([\ S] *) \}/) [1]; <br/> // new function, with a parameter, return the private variable of the target function <br/> var newfn = function ('A', 'var get = '+ Get +' \ n' + body + "\ n; return get (a) "); <br/> return newfn (t); // execute the new function <br/> }; </P> <p> var parent = function () {<br/> var P = 'private variable'; <br/> }; <br/> var pp = reveal (parent, 'P'); <br/> alert (PP) // Private variable! <Br/>
RunCode
Expand to a class factory.
Dom ={}; Dom. keys = function (OBJ) {var Results = []; for (var key in OBJ) {If (obj. hasownproperty (key) Results [results. length] = key;} return results;}; Dom. foreach = function (ARR, FN, bind) {If (typeof arr. foreach = "function") {arr. foreach (FN, bind);} else {for (VAR I = 0, n = arr. length; I <n; I ++) fn. call (bind, arr [I], I, arr); // bind, value, key, arr}; Dom. reveal = function (FN) {var g ET = function (target) {return eval (target) ;}; // obtain the original function var body = fn. tostring (). Match (/function. +? \ {([\ S] *) \}/) [1]; var Klass = function ('this. get = '+ Get +' \ n' + body); Klass. prototype = fn. prototype; // obtain the prototype var keys = Dom of the original function. keys (FN); // gets all the static attributes of the original function Dom. foreach (keys, function (key) {Klass [Key] = FN [Key]}); Return Klass ;} // **************************** var parent = function () {VaR _ p = 'this is a private variable ';}; parent. _ S = "static property" parent. prototype. _ p = "prototype attribute" Var son = Dom. reveal (parent); var S = new son; var pp = S. get ('_ p'); alert (son. _ s) Alert (PP) Alert (S. _ p)
<Br/> Dom ={}; <br/> Dom. keys = function (OBJ) {<br/> var Results = []; <br/> for (var key in OBJ) {<br/> If (obj. hasownproperty (key) <br/> results [results. length] = key; <br/>}< br/> return results; <br/>}; <br/> Dom. foreach = function (ARR, FN, bind) {<br/> If (typeof arr. foreach = "function") {<br/> arr. foreach (FN, bind); <br/>} else {<br/> for (VAR I = 0, n = arr. length; I <n; I ++) <br/> Fn. call (bind, arr [I], I, arr); <br/>}< br/>}; <br/> Dom. reveal = function (FN) {<br/> var get = function (target) {<br/> return eval (target); <br/> }; <br/> // obtain the original function body <br/> var body = fn. tostring (). match (/function. +? \ {([\ S] *) \}/) [1]; <br/> var Klass = function ('this. get = '+ Get +' \ n' + body); <br/> Klass. prototype = fn. prototype; // obtain the prototype of the original function <br/> var keys = Dom. keys (FN); // obtain all static attributes of the original function <br/> Dom. foreach (keys, function (key) {<br/> Klass [Key] = FN [Key] <br/>}); <br/> return Klass; <br/>}</P> <p> var parent = function () {<br/> VaR _ p = 'this is a private variable '; <br/> }; <br/> parent. _ S = "static property" <br/> parent. prototype. _ p = "prototype attributes" <br/> var son = Dom. reveal (parent); <br/> var S = new son; <br/> var pp = S. get ('_ p'); <br/> alert (son. _ s) <br/> alert (PP) <br/> alert (S. _ p) <br/>
Run code