部門:qq音樂
方式:電話面試
javascript篇
自我介紹
學習前端多久
javascript常見的資料類型有哪些
<code>typeof null</code>傳回什麼
原始類型和對象類型有什麼差別
如何判斷是<code>object</code>還是<code>array</code>
有接觸過閉包嗎?閉包有哪些應用場景
js的垃圾回收機制
如何自己實作一個<code>new</code>
如何自己實作一個<code>instanceof</code>
原型鍊的最頂層是什麼(<code>null</code>)
原型鍊的繼承方式有哪些,舉例說明
原型鍊有沒有什麼缺點
子類<code>child</code>繼承了父類的<code>parent</code>之後,<code>oarent</code>有一個屬性name。這時<code>new</code>一個子類的執行個體<code>b</code>,如果修改了<code>b.name</code>是否會修改父類上的<code>name</code>屬性
http篇
如何用<code>ajax</code>原生實作一個<code>post</code>請求(xmlhttprequest)
其中有<code>readystate</code>,解釋一下它的每個值代表的含義
使用<code>ajax</code>如何解決跨域問題
使用<code>jsonp</code>時服務端傳回什麼樣的資料,如何處理(callback(json拼好))
dom篇
假設一個 <code>ul</code> 下有一萬個 <code>li</code>,<code>li</code> 的 <code>innerhtml</code> 是從 <code>0</code>到 <code>9999</code>,當點選某個 <code>li</code>時輸出該 <code>li</code> 代表的值,如何實作
<code>windowonload</code> 和 <code>domready</code> 哪個先觸發
浏覽器安全篇
講講 <code>csrf</code> 和 <code>xss</code> 攻擊的原理,和解決方式
假設有兩個 <code>tab</code>,一個是 <code>a.qq.com</code>,另一個是黑客的域名,你在黑客的域名下向 <code>a.qq.com</code> 發起了一個請求,請問是否會帶上 <code>a</code> 頁面的 <code>cookie</code>
算法篇
爬樓梯
答案:
共8種。包括7種基本資料類型:
表示空:<code>null</code>,<code>undefined</code>
三大件:<code>string</code>,<code>number</code>,<code>boolean</code>
兩個新類型:<code>bigint</code>,<code>symbol</code>
和<code>object</code>
解讀:
這裡是按照 mdn 的說法回答的。也可以回答為 7 種 基本 資料類型,和 引用 類型。引用類型包括:
普通對象 <code>object</code>
數組對象 <code>array</code>
正則對象 <code>regexp</code>
函數 <code>function</code>
這是目前最準确的方法,網上流傳了很多種判斷方法,這個是最核心的,答出這個就可以了。
除此之外,還有一種提問方式是 如何判斷是不是 array,這是偏向于考察 es6 新增的數組方法了,可以用<code>array.isarray()</code>和<code>instanceof</code>來回答。
2012 年以前,相對舊的浏覽器使用「引用-計數」算法(reference counting)進行垃圾回收,缺點是會由于循環應用導緻記憶體洩漏。現代浏覽器都使用「标記-清除」算法(mark and sweep),即從全局對象作為的根節點開始,向下查詢引用的對象,沒有查詢到的對象都将被回收。
相對舊的浏覽器如 ie6,ie7 是使用「引用-計數」法進行垃圾回收的。
先通過一個例子來了解 <code>new</code> 的作用吧:
代碼中我們建立了一個對象 <code>person</code>,它具有屬性 <code>name</code>,且在<code>person.prototype</code> 上定義了函數 <code>sayname</code>。
當我們通過 <code>new</code>建立一個新的執行個體 <code>p</code> 時,便同時具有了屬性 <code>p.name</code> 和 <code>p.sayname()</code>,關系如下圖:
知道了原理,就可以自己實作了。也就是說,自己寫一個函數 <code>funcnew()</code>,使得 <code>const p = new person('orange')</code> 和 <code>const p = funcnew('orange')</code> 得到的 <code>p</code> 完全相同,于是得到了答案中的代碼。
答案中最後一行代碼如何了解?
前面的例子我們隻考慮了 <code>person</code> 中沒有傳回值的情況,如有有傳回值,<code>new</code> 一個執行個體将會受到 <code>person</code> 中傳回值的影響。比如說:
上面的例子中,如果傳回了一個對象,我們需要傳回該對象;如果不是對象,則 <code>return</code> 沒用,正常處理。
這個問題既考察了 <code>instanceof</code> 的原理,又考察了原型鍊,還考察了代碼能力,是一個好問題。
在實作代碼中,我們判斷 <code>leftvalue</code> 是否為 <code>rightvalue</code> 的執行個體,思想是在 <code>leftvalue</code> 的原型鍊上,即 <code>leftvalue.__proto__</code> 上尋找是否存在 <code>rightvalue.prototype</code>。原理圖如下:
這需要我們熟練掌握原型鍊的相關知識。
假設一個 <code>ul</code> 下有一萬個 <code>li</code>,<code>li</code> 的 <code>innerhtml</code> 是從 <code>0</code> 到 <code>9999</code>,當點選某個 <code>li</code> 時輸出該 <code>li</code> 代表的值,如何實作
采用事件委托:
首先,我們當然不可能為每一個 <code>li</code> 标簽手動添加一個 <code>click</code> 事件(容易累死);其次,我們可能會想到使用 <code>for</code> 循環周遊每個元素,然後為其添加 <code>click</code> 事件,但這樣會頻繁操作 dom,降低性能,卡到爆炸。
而事件委托意義就在于此:減少 dom 操作,進而減少浏覽器的重繪與重排次數,提升性能。
事件委托的原理是,将 <code>li</code> 上監聽的 <code>click</code> 事件委托到 <code>ul</code>上。這裡運用到了 事件冒泡 的機制,即 <code>onclick</code> 事件以 <code>li -> ul -> body -> html -> document</code> 的冒泡順序逐漸傳遞。
是以,我們可以選擇在其中的 <code>ul</code> 上監聽 <code>click</code> 事件,進而實作事件委托。
如何建立 100000 個 <code><li></code> 呢?總不能複制粘貼 100000 次吧?
建立 100000個 <code><li></code> 标簽,思路是将 <code>0∼9999</code> 儲存在數組中,然後轉化為字元串 <code>"<li>0</li><li>1</li>...<li>9999</li>"</code>,最後将他們作為 <code>ul</code> 标簽的 <code>innerhtml</code> 即可。