JavaScript 有什么奇技淫巧?

关注者
2855
被浏览
157839

64 个回答

向下取整:
var a = ~~1.2; //1
这个补充一下,还可以用位右移符>>
var a = 3.4>>0; //3 
但是两者最好都只用在正整数上,因为只是舍掉了小数部分。Math.floor(-1.2)应该为-2,这两种方法的结果为-1

转数字
var time = + new Date();

设默认值
function foo(bar){
    var foobar = bar || 'default'; 
    //bar 为 undefined, null, "", 0, false, NaN 时最后都得到'default'
}

//坑
[]||"aa"; //[]
{}||"aa"; //SyntaxError
({})||"aa";//Object {}

NaN的坑
//NaN - 不是一个数字
isNaN(a);
//检查是不是 "不是一个数字" ..

isNaN(null);//false
//实际上是null被转为0了,表面上"null 不是一个 不是数字 的东西"。wtf...

UNICODE 用作变量名
var \u4f60\u597d = "\u4f60\u597d";
var b = {};
b.\u4f60\u597d = \u4f60\u597d;
console.log(b);//Object {你好: "你好"}
console.log(b.你好);// "你好"
console.log(b.\u4f60\u597d);// "你好"

console.log("你"==="\u4f60");//true

数组传递和复制
var a = [1,2,3];
var b = a;
delete b[1];
console.log(a);//[1, undefined × 1, 3]

var a = [4,5,6];
var b = a.slice(0);
delete b[1];
console.log(a);//[4,5,6]
console.log(b);//[4, undefined × 1,6]

对象与Function
console.log(typeof Function);//"function"
console.log(typeof Object);//"function"

函数声明
aa();
function aa(){return true;} //true

bb();
var bb = function(){return true;} //TypeError

toString()
2.toString();//SyntaxError
2 .toString(); //"2"
2..toString(); //"2"
(2).toString(); //"2"

[1,[2,"abc","",0,null,undefined,false,NaN],3].toString();
//"1,2,abc,,0,,,false,NaN,3"

for in 暴露原型链属性
Object.prototype.foo = 1;

var obj = new Object();
obj.bar = 1;
for(var p in obj){
    console.log(p);//bar,foo 都遍历出来了。可以用hasOwnProperty()过滤原型链属性

}

switch代替if else
 switch (true) {  
        case (a > 10):  
            do_something();
            break;
        case (a < 100):  
            others();  
            break;  
        default:
            ;  
            break;  
    };  

太多了...
js是一门强大的语言。 对黑客来说,这是绕过WAF的利器,比如当字母和数字都无被WAF屏蔽的时候,你可以这样玩:

1 = !+[] = ++[[]][+[]]


2 = !+[]+!+[] = ++[++[[]][+[]]][+[]]


3 = !+[]+!+[]+!+[] = ++[++[++[[]][+[]]][+[]]][+[]]


a 的获取方式 false[1] 或者是 NaN[1]


false = ([![]]+[])

// 空的array, NOT一下,加上中括号后再通过+[] 转化成string


1 = ++[[]][+[]]

//前面解释过了,或者用!+[] 也可以。


于是a可以用这个表达: ([![]]+[]) [++[[]][+[]]]


同理l的是false[2], 等于 ([![]]+[])[++[++[[]][+ []]][+[]]]


e 是 false[4], r 和 t 通过 true来获得,而true就是false去掉NOT符号的结果


最后alert也就是这个:


(+[][+[]]+[])[++[[]][+[]]]+([![]]+ [])[++[++[[]][+[]]][+[]]]+([!![]]+ [])[++[++[++[[]][+[]]][+[]]][+[]]]+ ([!![]]+[])[++[[]][+[]]]+([!![]]+ [])[+[]]



还有一些比较复杂的字母需要绕一下,比如说 window 对象 的构造:

(1,[].sort)() = window


sort的 s通过false, r t 通过 true, o 通过 [object Object]

于是 window.alert(1) 就是如下代码:



([],[][([![]]+[])[++[++[++[[]][+[]]][+[]]] [+[]]]+([]+{})[++[[]][+[]]]+([!![]]+[])[++ [[]][+[]]]+([!![]]+[])[+[]]])()[ (+[][+[]] +[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+ []]][+[]]] +([!![]]+[])[++[++[++[[]][+[]]] [+[]]][+[]]]+([!![]]+[])[++ [[]][+[]]]+ ([!![]]+[])[+[]]](++[[]][+[]])

为什么?