• 访问私有变量


    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)
    

  • 相关阅读:
    常量的三种定义方式和static在c语言中的三种修饰
    字符串的定义方式;输出和计算长度时的细节
    指针小白:修改*p与p会对相应的地址的变量产生什么影响?各个变量指针的长度为多少?
    习题 :任意输入十个数按大小排序;构造简单数学运算模块(形参和实参)
    for循环简单实例(打印乘法表,打印菱形)
    几个简单if程序的细节比较与加法程序设计
    冒泡排序法,两个数组内容的互换,两个变量之间的交换
    scanf加不加 ?
    jqplot导入包小结
    使用ajax与jqplot的小体会
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1642925.html
Copyright © 2020-2023  润新知