衆所周知,淘寶首頁在近期作了一次較大的更新。淘寶UED的各位大神們,頗有意思的在首頁代碼中放入了一個小彩蛋,引發網友驚呼「前端工程師在HTML中居然擼出一個妹紙來」,上jb:javascript
是否是頗有意思呢?關於,這個妹紙的身份呢?算了,愚安仍是告訴你們吧!她是淘寶視覺顧問@amei_shin,你們不要告訴她是愚安在這裏八卦的哦!html
固然,愚安把這個貼出來,首先是讓你們瞭解到寫代碼有時候,還算是比較開心的事情,又或是本身能夠找點方法讓寫代碼變得有趣起來;而後就是想更你們分析下,這段代碼是什麼意思,有什麼執行效果,怎麼樣才能寫出這樣的js彩蛋。前端
咱們知道js裏的Function("","")返回一個匿名函數;因此,java
javascript:Function('a,l,i,t,b,u,e,d',"a=['"+[ ' :h8G895r,', ' ,hA@@@@@@@@#&5:', ' S#@Hs:;h&@@@@@@#3', ' 8@@8 r&@@@@@@A;', ' 9@@M;:r1r :9#@@@@@M;', ' h@@@&ii391, ;8GH@@@@B.', ' :#@@@8 ;5r:. iA@@@5', ' .8@@@@G ;s,: .A@@#5', ' rB@@@@Bs, .::. .;, ;@@@M ,:', ' .XM@@@@#&; sh;,..,. h@@@B sr', ' .X@@@@@H@As, ;9@@s8# si', ' sHM@@@@@@@@BXSsi::r19&@@@G 5,s1.', ' rM#@@@@@@@@@B#@#&35s38#@@@8 i3;,', ' r&M@@@@@@@@@S:sS3r ,hS@@@@@&,,i:;;.', ' ,FGP@.@e@g@g@& :;:SGM@@@@@&.:,:8&hir:', ' ;&@F@P@.@e@gBg 1HM@@@@@@Ms:,;r5h;H@,', ' G(@"@%@c@j@o: rsi&@@@@@@&: ,:,X9,.', ' riMn@ @u@s@%@c#srh G@@@@@@@B3;:,.:s::;', ' :i&d@u@.@m@j@@@t@a@oAbXaBo@.@c@o@mB"1)i;,:;;', ' sGi.;3#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#9rr;,,,i,', ' h1: ,S#@@@@@@@@@@@@@@@@@@@@@@@@@@@@Xhi. ,r', ' 13i,. :X@@@@@@@@@@@@@@@@@@@@@@@@@@MXh...,;r:', ' iXh;,.. 9@@@@@@@@@@@@@@@@@@@@@@@@@@MA9hr;:is:', ' ,X9r:,,.. 3@@@@@@@@@@@@@@@@@@@@@@@@@@@@G5s;;sh,', ' 9&5i;:,,. S@@@@@@@@@@@@@@@@@@@@@@@@@@@B9hsrsh1', ' sBG93&73&53&33&13&92&72&52&32&12&91&71&51&31&11', ' &9&7&5&3&1:81,71&51&31&11&9&7&5&3&1:71,11&9&7&5&', ' 3&1:61,31&11&9&7&5&3&1:51,31&11&9&7&5&3&1:41@631' ].join("','")+"'];l=a.join(i='').replace(/\\s+/g,i)[d='split'](i).reverse().join(i);l=l.substr(l.indexOf('@')+1,parseInt(l))[d](/[,:]/);while(t=l[b='shift']()){u=l[b]()[d]('&');while(e=u[b]())i+=a[t].replace(/^\\s+/g,'').charAt(+e);}eval(i);")();
其實就是定義了以下的匿名函數:web
function anonymous(a,l,i,t,b,u,e,d /**/) { a=[' :h8G895r,',' ,hA@@@@@@@@#&5:',' S#@Hs:;h&@@@@@@#3',' 8@@8 r&@@@@@@A;',' 9@@M;:r1r :9#@@@@@M;',' h@@@&ii391, ;8GH@@@@B.',' :#@@@8 ;5r:. iA@@@5',' .8@@@@G ;s,: .A@@#5',' rB@@@@Bs, .::. .;, ;@@@M ,:',' .XM@@@@#&; sh;,..,. h@@@B sr',' .X@@@@@H@As, ;9@@s8# si',' sHM@@@@@@@@BXSsi::r19&@@@G 5,s1.',' rM#@@@@@@@@@B#@#&35s38#@@@8 i3;,',' r&M@@@@@@@@@S:sS3r ,hS@@@@@&,,i:;;.',' ,FGP@.@e@g@g@& :;:SGM@@@@@&.:,:8&hir:',' ;&@F@P@.@e@gBg 1HM@@@@@@Ms:,;r5h;H@,',' G(@"@%@c@j@o: rsi&@@@@@@&: ,:,X9,.',' riMn@ @u@s@%@c#srh G@@@@@@@B3;:,.:s::;',' :i&d@u@.@m@j@@@t@a@oAbXaBo@.@c@o@mB"1)i;,:;;',' sGi.;3#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#9rr;,,,i,',' h1: ,S#@@@@@@@@@@@@@@@@@@@@@@@@@@@@Xhi. ,r',' 13i,. :X@@@@@@@@@@@@@@@@@@@@@@@@@@MXh...,;r:',' iXh;,.. 9@@@@@@@@@@@@@@@@@@@@@@@@@@MA9hr;:is:',' ,X9r:,,.. 3@@@@@@@@@@@@@@@@@@@@@@@@@@@@G5s;;sh,',' 9&5i;:,,. S@@@@@@@@@@@@@@@@@@@@@@@@@@@B9hsrsh1',' sBG93&73&53&33&13&92&72&52&32&12&91&71&51&31&11',' &9&7&5&3&1:81,71&51&31&11&9&7&5&3&1:71,11&9&7&5&',' 3&1:61,31&11&9&7&5&3&1:51,31&11&9&7&5&3&1:41@631'];
l=a.join(i='').replace(/\s+/g,i)[d='split'](i).reverse().join(i);
l=l.substr(l.indexOf('@')+1,parseInt(l))[d](/[,:]/);
while(t=l[b='shift']()){
u=l[b]()[d]('&');
while(e=u[b]())
i+=a[t].replace(/^\s+/g,'').charAt(+e);
}
eval(i);
}
這樣看是否是以爲很累啊,咱們一行行來看:chrome
a = ["",""....]//定義一個多個字符串組成數組,字符串中含有空格,也就是構成代碼中的那些個妹紙 i = ''//定義一個空字符串 d = 'split';b='shift';//因爲js中對象成員能夠以數組鍵值對的形式訪問,因此下面有不少[d]()這種方法調用對象方法的形式,這裏指定兩個方法 l = a.join('').replace(/\s+/g,'').split('').reverse().join('');//這裏a通過合爲字符串,去空格,split爲單字符組成的數組,反向,從新組成爲字符串,即 l= "136@13:1&3&5&7&9&11&13&15&17&19&21&23&25&27&29&31&33,14:1&3&5&7&9&11&13,15:1&3&5&7&9&11&13,16:1&3&5&7&9&11,17:1&3&5&7&9&11&13&15&17,18:1&3&5GBs1hsrsh9B@@@@@@@@@@@@@@@@@@@@@@@@@@@S.,,:;i5&9,hs;;s5G@@@@@@@@@@@@@@@@@@@@@@@@@@@@3..,,:r9X,:si:;rh9AM@@@@@@@@@@@@@@@@@@@@@@@@@@9..,;hXi:r;,...hXM@@@@@@@@@@@@@@@@@@@@@@@@@@X:.,i31r,.ihX@@@@@@@@@@@@@@@@@@@@@@@@@@@@#S,:1h,i,,,;rr9#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#3;.iGs;;:,:ih13B@@@@@@@@@BXXXAM@@@@@@@@@@@@@;@)&":;::s:.,:;3B@@@@@@@Gmro#c@.@o@a@b@oMar.,9X,:,:&@@@@@@&isr:t@@@j@m@.@uG,@H;h5r;,:sM@@@@@@MH1dBi@h@s@c@%@s;:rih&8:,:.&@@@@@MGS:;:u@@n@i@o@jGc,.%;"i(,g@g@e@.hPF3&s&Sg@g@e@.@PMFr,;3i8@@@#83s53&#@#B@@@@@@@@@#Mr.1s,5G@@@&91r::isSXB@@@@@@@@MHsis#8s@@9;,sA@H@@@@@X.rsB@@@h.,..,;hs;&#@@@@MX.:,M@@@;,;..::.,sB@@@@Br5#@@A.:,s;G@@@@8.5@@@Ai.:r5;8@@@#:.B@@@@HG8;,193ii&@@@h;M@@@@@#9:r1r:;M@@9;A@@@@@@&r8@@83#@@@@@@&h;:sH@#S:5&#@@@@@@@@Ah,,r598G8h:" l=l.substr(l.indexOf('@')+1,parseInt(l)).split(/[,:]/);//即截取l中的一段,按照,或:拆分紅數組 l = ["13", "1&3&5&7&9&11&13&15&17&19&21&23&25&27&29&31&33", "14", "1&3&5&7&9&11&13", "15", "1&3&5&7&9&11&13", "16", "1&3&5&7&9&11", "17", "1&3&5&7&9&11&13&15&17", "18", "1&3&5"]; //接着進入循環對這個數組進行處理; while(t=l.shift()){ u=l.shift().split('&'); while(e=u.shift()) i+=a[t].replace(/^\s+/g,'').charAt(+e); } //獲得i ="FP.egg&&FP.egg("%cjoinus%cshidu.mj@taobao.com")"
eval(i);c#
FP.egg&&FP.egg("%cjoinus%cshidu.mj@taobao.com");數組
先來看看什麼效果,在chrome的console裏跑一下看看(爲何是chrome,接下來會說),因爲是Taobao頁面的函數,因此務必在淘寶首頁下的控制檯執行;瀏覽器
首先控制檯會打印:,這裏是淘寶UED的博客,和淘寶前端的求職郵箱。前端工程師
而後,頁首會出現
能夠看出,左上角會出現「chrome體感試驗的標籤」,這裏會瀏覽器會告訴你該頁面請求調用你的攝像頭,(這裏運用的是webrtc的技術,有興趣的小夥伴能夠留言,我有空會作一個webrtc技術的入門帖,雖然我也不是很懂),開啓攝像頭後,隨意在攝像頭下搖晃一個物體(固然,你要是以爲本身搖起來比較high的話,愚安也不反對),到了必定頻率,溫度計會到頂,而後會有一串頗有意思的動畫,介紹一下淘寶UED的各個部門主要成員,這裏愚安就不一一貼圖了,感興趣的小夥伴,能夠本身運行一下看看。這裏須要說明一下的是,若是你不開啓攝像頭,溫度計上升的動畫會跳過,直接進入UED的部門介紹動畫。鑑於,我以爲搖晃物體使溫度計上升還算是蠻有意思的事情,建議你們都接受提醒,試一下。
關於怎麼實現,這個過程,就在FP.egg裏,你們本身研究下,仍是有點複雜的,我就不繼續貼了,算是個拋磚引玉吧,小夥伴兒們加油!
function (c){if(a.ie&&a.ie<9){return e(k.all,1)}e(k.all,0);setTimeout(function(){r?d():(k.each(s,function(h){(new Image()).src=h}),f(b,d))},2000);if(p=n[p]){if(a.chrome){p.log("%c",g[0]),c&&p.log(c,g[1]+"padding:3px 8px;",g[2]),p.log("%cued blog%chttp://ued.taobao.com/",g[1],g[2])}else{p.log(c.replace(/%c([^%]+)%c(.+)/,"$1: $2"))}}}
這篇隨筆的主要目的,其實就是鼓勵你們,尤爲是想從事前端開發的同窗們,多去看看一些大站的代碼;好比,百度,在控制檯能夠看到,打印以下信息: