⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 js压缩.htm

📁 js压缩
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<title>经典的Javascript 构缩加密程序</title>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312" />
<script type="text/javascript">
function ICommon(that)
{
  if(that != null)
  {
     that.inherit=Common.prototype.inherit;       // 继承
     that.specialize=Common.prototype.specialize;
  }
  return that
};

// 注释后的代码是原来的代码,前面的是我改写的
// 对象的静态方法,没有用prototype,因此不需要实例化就可以用的
ICommon.specialize = function(p,c)
{
  p || (p = {});            // if(!p)p={};
  // constructor 属性保存了对构造特定对象实例的函数的引用
  c || (c = p.constructor); // if(!c)c=p.constructor;
  // 如果c仅仅是Object而不是function
  if(c == {}.constructor)c = new Function("this.inherit()");
  
  c.valueOf = new Function("return this");
  c.valueOf.prototype = new this.valueOf;
  c.valueOf.prototype.specialize(p);
  c.prototype = new c.valueOf;
  c.valueOf.prototype.constructor = c.prototype.constructor = c;
  // 祖先,父类
  c.ancestor = this;
  // 调用者
  c.specialize = arguments.callee;
  c.ancestorOf = this.ancestorOf;
  return c
};

ICommon.valueOf = new Function("return this");

// 定义原型后就可以拿来实例化了
ICommon.valueOf.prototype = {
  constructor:ICommon,
  inherit:function()
  {
     // arguments.callee = 正被执行的 Function 对象
     return arguments.callee.caller.ancestor.apply(this, arguments)
  },
  specialize:function(that)
  {
     if(this == this.constructor.prototype && this.constructor.specialize)
     {
        return this.constructor.valueOf.prototype.specialize(that)
     }
     for(var i in that)
     {
        switch(i)
        {  // 如果是这些方法就跳过
           case"constructor":case"toString":case"valueOf":continue
        }
        // 把当前类中一些东西复制过去
        if(typeof that[i] == "function" && that[i] != this[i])
        {
           that[i].ancestor = this[i]
        }
        this[i] = that[i]
     }
     // 如果当前对象的toString和that的不相等,并且不等于Object的toString
     if(that.toString != this.toString && that.toString != {}.toString)
     {
        that.toString.ancestor = this.toString;
        this.toString = that.toString
     }
     return this
  }
};

function Common(){};

// this = window, 想迷惑我啊
// 这里将ICommon.specialize设置为this.Common的父类,由属性ancestor支持
// 
this.Common = ICommon.specialize({
  // constructor:Common = this.Common = window.Common
  constructor:Common,
  toString:function()
  {
     return"[common "+(this.constructor.className ||"Object")+"]"
  },
  instanceOf:function(klass)
  {
     return this.constructor == klass || klass.ancestorOf(this.constructor)
  }
});

Common.className = "Common";
Common.ancestor  = null;

// 判断Common是否是klass的祖先类
Common.ancestorOf = function(klass)
{
  while(klass && klass.ancestor != this) klass = klass.ancestor;
  return Boolean(klass)
};

Common.valueOf.ancestor = ICommon;

// 主解析程序
function ParseMaster()
{
  var E = 0, R = 1, L = 2;
  // G 全局中找(
  // S 非全局中找到$加上一个数字的串
  // I 非全局中找到串开头$加上一个以上数字的串结尾
  // T 非全局中找两对对单双引号 + 任何非单双引号字符 + 两对对单双引号
  // ES 查找1个\开始的串
  // Q 找到一个单引号
  // DE 找x01字符开头和结尾的串
  var G = /\(/g, S = /\$\d/, I = /^\$\d+$/,T = /(['"])\1\+(.*)\+\1\1$/, ES = /\\./g, Q = /'/, DE = /\x01[^\x01]*\x01/g;
  // 方便下面的调用,因为在下面的匿名函数里的this不等于这里的this,但是却能访问这里的变量
  var self = this;
  this.add = function(e, r)
  {
     r || (r = ""); // if(!r)r = "";
     // 下划线开头的变量或函数名,不要被他迷惑
     // _14 = s.replace(/\\./g, ''), 将单行中”\开头 + 单个任何字“符去除
     var l = (_14(String(e)).match(G) || "").length + 1;
     // 检查r中是否有$加上一个数字的串
     if(S.test(r))
     {
      // 检查开头到结尾串开头$加上一个以上数字的串结尾
      if(I.test(r))
      {
        // 将r设置为r中$后数字的 - 1的数
         r = parseInt(r.slice(1)) - 1
      }
      else
      {
         // e中(的个数 + 1
         var i = l;
         // r中有单引号则q = " ,否则 = '[单引号]
         var q = Q.test(_14(r)) ? '"' : "'";
         // 将r用$i ~ $1的串分解为数组---如果r很长,估计有效率问题
         // 然后在用q的引号包装起来的"+a[o+"+i+"]+"连接起来
         // 不过我在想,这个动作似乎可以用正则表达式来完成
         // r = r.replace(/\$(\d)/g, function($0, $1){return q + "+a[o+" + ($1 - 1) + "]+" + q})
         // 可是他为什么不这样用呢 
         while(i)r = r.split("$" + i--).join(q + "+a[o+"+i+"]+" + q);
         
         // 两个参数:a,o, r.replace(T,"$1")是将r中连续的两个单双引号替换为一个
         // 噢,return后居然不给空格也可以,看来也只有javascript才支持这样的语法了
         r = new Function("a ,o", "return" + q + r.replace(T,"$1") + q)
      }
     }
     _33( e || "/^$/", r, l)
  };
  this.exec = function(s)
  {
     _3.length=0;
     return _30(_5(s,this.escapeChar).replace(new RegExp(_1,this.ignoreCase?"gi":"g"),_31),this.escapeChar).replace(DE,"")
  };
  this.reset=function()
  {
     _1.length = 0
  };
  
  var _3=[];
  var _1 = [];
  // slice中的 -1 指向* 中的最后一个字符,并作为提取操作的结束位置。
  var _32 = function(){ return"(" + String(this[E]).slice(1,-1)+")" };
  // 重写_1这个数组的toString
  _1.toString = function(){return this.join("|")};
  
  function _33()
  {
     // arguments该对象代表正在执行的函数和调用它的函数的参数,这里表示重写他的toString方法
     arguments.toString = _32;
     // 这里默认调用了上面的toString方法[只处理E下标的变量],他又在迷惑人
     _1[_1.length] = arguments
  }
  function _31()
  {
     if(!arguments[0]) return"";
     var i=1,j=0,p;
     while(p=_1[j++]){
      if(arguments[i]){
       var r=p[R];
       switch(typeof r){
        case"function":return r(arguments,i);
        case"number":return arguments[r+i]
       }
       var d=(arguments[i].indexOf(self.escapeChar)==-1)?"":"\x01"+arguments[i]+"\x01";
       return d+r
      }else i+=p[L]
     }
  };
  function _5(s,e)
  {
     // replace的第二参数居然用function
     // 关于第二参数描述:在 Jscript 5.5 或更新版本中,replaceText 参数也可以是返回替换文本的函数。
     // m,c相当于$0,$1,$2...., 第一个参数是正则表达式全部匹配内容,第二个开始以后的是模式中()部分内容
     return e ? s.replace(new RegExp("\\"+e+"(.)","g"), function(m,c){ _3[_3.length]=c; return e }):s
  };
  function _30(s,e){var i=0;return e?s.replace(new RegExp("\\"+e,"g"),function(){ return e+(_3[i++]||"")}):s };
  function _14(s){return s.replace(ES,"")}
};


ParseMaster.prototype = { 
	constructor:ParseMaster,
	ignoreCase:false,
	escapeChar:"" 
};

// IE 5.0
if(/MSIE 5.0/.test(navigator.userAgent))
   new function()
   {
   	// 将o用到f函数中当作f的this,并以a为他的参数
   var ap = function(f,o,a){f.apply(o,a)};
   
   // 很奇怪, if(''.replace(/^/,String))经过测试永远都不为真啊,那么为什么要这样呢
   // 那么我们姑且认为,String的prototype.replace将来肯定被他改变而执行特殊的用途
   // 他的意思是:如果没有replace方法就给他写一个,看来是为了兼容其他浏览器,或者兼容低版本的浏览器
   if(''.replace(/^/, String))
   {
	    var _28 = String.prototype.replace;
	    // e是一个正则表达式
	    // r是一个函数
	    // 看来,这是一个解码或编码的过程
	    var _29 = function(e, r)
	    {
	    	 // 看来this是一个String对象
		     var m, n = "", s = this;
		     // 这里可以看出e是一个正则表达式,index 查找字符串中第一个成功匹配的开始位置
		     // lastIndex 被查找字符串中下一次成功匹配的开始位置
		     // 数组的0元素包含了完整的匹配,而第1到n元素中包含的是匹配中出现的任意一个子匹配
		     // 如果为正则表达式设置了全局标志,exec 从以 lastIndex 的值指示的位置开始查找。如果没有设置全局标志,exec 忽略 lastIndex 的值,从字符串的起始位置开始搜索。
         // LastIndex 属性中包含了匹配中最后一个字符的下一个位置。
		     while( s && (m = e.exec(s)))
		     {
			      n += s.slice(0, m.index) + ap(r, this, m);
			      s = s.slice(m.lastIndex)
		     }
		     return n + s
	    };
	    // e是一个正则表达式
	    // r是一个函数或串
	    String.prototype.replace = function(e,r)
	    {
	    	 // 如果r为函数就用_29来代替他,那就是说如果这里想用他,就可以用new function(){}或者new Fucntion()来迷惑他人,而实际执行的是_29
	    	 // 如果不是就用String原来的replace
	       this.replace = (typeof r == "function") ? _29 : _28;
	     return this.replace(e,r)
	    }
   }
   // if(!Function.apply)也是测试发现他的里面的代码不回执行,为什么?因为Boolean(!Function.apply) == false
   if(!Function.apply)
   {
	    var APPLY = "apply-" + Number(new Date);// Number(new Date) = new Date().getTime()
	    // f 是个function
	    // o 是一个Object
	    // a 是一个参数数组,个数是0 - 4
	    // 将a作为f函数的参数执行并返回结果
	    ap = function(f,o,a)
	    {
	     var r;
	     o[APPLY] = f;
	     switch(a.length)
	     {
		      case 0: r = o[APPLY]();break;
		      case 1: r = o[APPLY](a[0]);break;
		      case 2: r = o[APPLY](a[0], a[1]);break;
		      case 3: r = o[APPLY](a[0], a[1], a[2]);break;
		      case 4: r = o[APPLY](a[0], a[1], a[2], a[3]);break;
		      default:var aa = [], i = a.length - 1; do aa[i] = "a["+i+"]";while(i--);eval("r = o[APPLY](" + aa + ")")
	     }
	     delete o[APPLY];
	     return r
	    };
	    // 把调用者的对象作为他的父类并用参数调用他ap
	    if(typeof ICommon == "function") ICommon.valueOf.prototype.inherit = function()
	    {
	        return ap(arguments.callee.caller.ancestor,this,arguments)
	    }
   }
   // 这看上去和上面一样,因为[].push在IE下永远为true,结果if内的代码得不到执行
   // 看来他的意思是说,如果没有push方法,那么他就给他写一个---难道其他浏览器里没有这个方法?
   if(![].push)
   Array.prototype.push = function()
   {
	    for(var i = 0; i < arguments.length; i++)
	    {
	       this[this.length] = arguments[i]
	    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -