日期:2014-05-16  浏览次数:20364 次

js世界里的诡异和离奇
num1:
    ba = function(a) {
        return a.call.apply(a.bind, arguments)
    }

(以上的代码出之于google的adsence广告投放的代码)

单纯的call和apply其实好解释,但如果想上面这样写,就有点绕了。

下面来分析上面这种写法
<script>
	var obj = { name : "cc"};
	var fun = function(){ 
		alert(1);
	};
	var fun2 = function(){ 
		alert(2);
	};
	
	alert(fun.call);
	alert(fun.call.apply);
    //c = fun2.call.apply(obj, ["123",12,676]);
    //error:Function.prototype.call called on incompatible [object Object]
	c = fun2.call.apply(obj, ["123",12,676]);
    //alert:1,arguments:[0] = 12 [1] = 676,this:"123"
</script>


得到以下结论:
1.fun2.call.apply相当于Function.prototype.call.apply
2.fun2.call.apply第一个参数是不能为obj,因为只有Function对象才有此方法,
3.fun2.call.apply(fun, ["123",12,676])可以简化为fun.call("123",12,676所以fun2.call其实只是浮云,call只能function才能调用,也揭示了call的底层实现:将第一个参数作为fun(call的调用者)的this,其他的作为参数

a.call.apply(a.bind, arguments)在看这段,为什么要这样写?
在于作者想让arguments里面第一个参数取代a.bind里面的this,那么可以这样:
var o = [].shift.call(arguments);
a.bind.apply(o,arguments);
这么说这句的目的有这些:简洁,犀利,你看不懂,作者很牛B,这还仅仅只是google投放的前10行里面的内容,哭啊~~~


num2
js获取函数调用者的函数名(原创)
(function(){
    B();
})()
function B(){
   var fun = arguments.callee.caller ? arguments.callee.caller : window;
   var fun_name = /^function\s+([^\(]*)\(/.exec(fun+"");
   fun_name = fun_name ? fun_name : "";
   alert(fun);
   alert(fun_name);
}

num3
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+ ($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__ [_+~$]+$_[_]+$$](_/_)



这句没出我意料的话,你应该没看懂,这句的结果输出的alert(1);


解析:
$=[] //$ : []

!$ //false
!$ + [] // false
(小结:[].toString()//"",-[]//0,[].valueOf()//[],这种结果显然[]直接调用的toString了,这里就牵涉到隐式转化问题,如果两个都不数字就当做字符串处理,所以结果是"false",由此确定第二个变量__ : "false")
~$ //-1
(小结: $:[[]], ~$,-$,+$相当于~"",-"",+""//结构都是-1,0,0可以暂时下个结论,数组参与数值运算的时候,都会转化成字符串在进行计算,但是-[1]//-1,-[1,2]//NaN,-[]//0 当只有一个数据的时候数组会原样输出,没有默认为0,现在后者站得住脚一些)
-~-~-~$//3
(小结:类似的方法可以求数组下标)
{}+$ //[object Object]
(小结,$ + {}//[object Object] )
!''//true
$$=($_=!''+$)[_/_]+$_[+$])]//"true"[1] + "true"[0] : "rt"
[_/_]//1


通过上述分析 得出:
$ == 未知
$$ == "rt"
$_ == "true"
_ == 3
__ == "false"

(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+ ($$=($_=!''+$)[_/_]+$_[+$])简化为:
("false")[3] + ("[object Object]")[1] + ("true")[1] + "true"[0]
即 : "s" + "o" + "r" + "t" //"sort"

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+ ($$=($_=!''+$)[_/_]+$_[+$])])() 简化为:
($=[]["sort"])()

$ == sort(Fun)
相当于给window对象增加了sort属性,而且sort返回的是this对象,这样就可以产生window对象,相当巧妙的地方


[__[_/_]+__ [_+~$]+$_[_]+$$](_/_)  简化为:
["false"[1] + "false"[2] + "true"[3] + "true"](1)
["a" + "l" + "e" + "rt"](1) //"[alert](1)"

window["sort"]()["alert"](1) -> window["alert"](1)

这种模糊代码的方式和手段很不错,值得借鉴和参考,可以越过脚本过滤,执行你想执行的

num4
document.write问题
<script>
document.write("<div id=\"webs\"></div>");
var ele = document.getElementById("webs");
alert(ele); //null
</script>

这结果有点纳闷,今天问了鹏哥才知道,原来document.write真正写入的时间是在当前script执行完之后才进行写入,所以在getElementById是不存在此元素的

处理方法:
<script>
document.write("<div id=\"webs\"></div>");
</script>
<script>
var ele = document.getElementById("webs");
alert(ele); //div
</script>


num5
for (var j = 0, len = d.length >>>0; j < len; j++) {...

今天看鹏哥里面有样一种写法d.length >>>0,第一次见过