访问javascript私有变量
来源:Ruby's Louvre 发布时间:2010-01-19 13:56:00
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)


猜你喜欢
- 问题:在数据库脚本开发中,有时需要生成一堆连续数字或者日期,例如yearly report就需要连续数字做年份,例如daily report
- 本文实例讲述了python中引用与复制用法。分享给大家供大家参考。具体分析如下:在python中,任何不可变对象是传值的,而可变对象是传引用
- 前言大风车,吱呀吱呦呦地转,这里的风景呀真好看!天好看,地好看……一首熟悉的歌曲,是否已经把你拉
- 本文实例讲述了Python获取运行目录与当前脚本目录的方法。分享给大家供大家参考。具体实现方法如下:import osimport sys#
- 防止客户机的请求互相干扰或者服务器与维护程序相互干扰的方法主要有多种。如果你关闭数据库,就可以保证服务器和myisamchk和isamchk
- transforms.Resize()的简单使用简单来说就是调整PILImage对象的尺寸,注意不能是用io.imread或者cv2.imr
- A朋友:你直接问。B朋友:你女朋友睡了后,偷偷拿电脑查。C朋友:咱们不吊死在一棵树上,不对劲就早点脱身。D朋友:我觉得A的不行,直接问容易打
- 百度AI提供了一天50000次的免费文字识别额度,可以愉快的免费使用!下面直接上方法:首先在百度AI创建一个应用,按照下图创建即可,创建后会
- 当你准备全面进军web标准时,有时候你是不是被表格的弄得焦头烂额呢?比如,原来使用“非法”的nobr现在要用什么来代替呢?今天,就让我来一个
- 本文实例讲述了Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法。分享给大家供大家参考,具体如下:问题输入第1行:字符串A第
- 下面这个截图,就是使用 schedule 定时执行 Notebook 的例子import scheduleimport timeimport
- 使用go语言的第三方包:github.com/pkg/sftp和golang.org/x/crypto/ssh实现文件和文件夹传输。1、创建
- 代码如下: 在ie下,貌似要改安全设置中的【对为标记为可安全执行脚本的ActiveX空间初始化并执行】那项 <html> <
- 每当有朋友过生日时,生日蛋糕自然是必不可少的,今天我们来看一下如何用 Python 画一个生日蛋糕。本文我们用到的 Python 库包括:t
- 本文实例讲述了JS实现FLASH幻灯片图片切换效果的方法。分享给大家供大家参考。具体实现方法如下:<!DOCTYPE html PUB
- 这是一种相对比较复杂的图表,但是仍然遵循上篇中提出的最基本的思路。本例中使用的定义列表标签dl可能平常我们见得不多,一般我们在做列表的时候通
- 阅读上一篇:垂直栅格与渐进式行距(上) 新问题来也匆匆,去也“冲冲”。距上次发布垂直栅格与渐进式行距(上)发布,已经不知不觉过去了
- 我就废话不多说了,直接上代码吧!def _int_iter(): """根据回文数的定义。首先生成
- for循环只是一个多一点的代码,同时循环添加到它。而所涉及的一个循环的共同任务是: 设置一些计数器变量的初始值。 请检查条件语句是正确的。
- MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(