访问私有变量
javascript作为一个动态语言,动态解析脚本的方法非常多,如万恶又万能的eval,低调的Function,IE独占的execScript,搭上DOM那边的script标签的text属性,W3C的script标签还能通过直接加文本节点或innerHTML解析脚本。有了这些方法,私有属性根本无处可藏。以前FF的eval更加邪恶,如果是通过模块模式构造的函数,获取其私有变量轻而易举。不过其bug已升级掉,就不说了。
说说其原理,就是内层作用域的函数可以随意访问外层作用域的变量。为此我们需要设计一个内部函数“打进”原函数的内部,不过直接修改原函数不太好,我们可以拷贝一个副本,但显然我们也用不着全单接收,只要一部分就可以。怎样只要一部分呢?所有函数都有一个叫toString的属性,我们拿它进行改造加入我们的内部函数,然后再通过动态解析复活它。
var reveal = function (fn,t){ //用于获取目标函数的私有变量 //作为新函数的内部函数而存在 var get = function (t){ return eval(t); }; //获取原函数的函数体 var body = fn.toString().match(/ function .+?\{([\s\S]*)\}/)[1]; //新函数,有一个参数,返回目标函数的私有变量 var newFn = Function( 'a' , 'var get =' + get + '\n' +body+ "\n;return get(a)" ); return newFn(t); //执行新函数 } |
用法:
var parent = function (){ var p = '私有变量' ; }; var pp = dom.reveal(parent, 'p' ); alert(pp) //私有变量! |
扩展一下,弄成一个类工厂。
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 get = function (target){ return eval(target); }; //获取原函数的函数体 var body = fn.toString().match(/ function .+?\{([\s\S]*)\}/)[1]; var klass = Function( 'this.get =' + get + '\n' + body); klass.prototype = fn.prototype; //获取原函数的原型 var keys = dom.keys(fn); //获取原函数的所有静态属性 dom.forEach(keys, function (key){ klass[key]= fn[key] }); return klass; } //**************************** var parent = function (){ var _p = '这是私有变量' ; }; parent._s = "静态属性" parent.prototype.__p = "原型属性" var son = dom.reveal(parent); var s = new son; var pp = s.get( '_p' ); alert(son._s) alert(pp) alert(s.__p) |
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?