📄 js压缩.htm
字号:
<!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 + -