常見前端面試題及答案(上)

前言

本文是在GitHub上看到一個大牛總結的前端常見面試題,很多問題問的都很好,很經典、很有代表性。上面沒有答案,我就整理了一下,從網上找了一些相關問題的答案。裏面有一部分問題的答案我也沒有進行考證,不少答案都來源於網絡,或許會有疏漏之處,僅供大家參考哦!(還有一部分問題答案還未整理,大家也可以自己搜索一下答案)

1.你能描述一下漸進增強和優雅降級之間的不同嗎?

優雅降級:Web站點在所有新式瀏覽器中都能正常工作,如果用戶使用的是老式瀏覽器,則代碼會檢查以確認它們是否能正常工作。由於IE獨特的盒模型佈局問題,針對不同版本的IE的hack實踐過優雅降級了,爲那些無法支持功能的瀏覽器增加候選方案,使之在舊式瀏覽器上以某種形式降級體驗卻不至於完全失效.

漸進增強:從被所有瀏覽器支持的基本功能開始,逐步地添加那些只有新式瀏覽器才支持的功能,向頁面增加無害於基礎瀏覽器的額外樣式和功能的。當瀏覽器支持時,它們會自動地呈現出來並發揮作用。

2.線程與進程的區別

一個程序至少有一個進程,一個進程至少有一個線程。線程的劃分尺度小於進程,使得多線程程序的併發性高。

另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。

線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

3.說說你對語義化的理解?

1.去掉或樣式丟失的時候能讓頁面呈現清晰的結構:html本身是沒有表現的,我們看到例如<h1>是粗體,字體大小2em,加粗;<strong>是加粗的,不要認爲這是html的表現,這些其實html默認的css樣式在起作用,所以去掉或樣式丟失的時候能讓頁面呈現清晰的結構不是語義化的HTML結構的優點,但是瀏覽器都有有默認樣式,默認樣式的目的也是爲了更好的表達html的語義,可以說瀏覽器的默認樣式和語義化的HTML結構是不可分割的。

2.屏幕閱讀器(如果訪客有視障)會完全根據你的標記來“讀”你的網頁。

3.PDA、手機等設備可能無法像普通電腦的瀏覽器一樣來渲染網頁(通常是因爲這些設備對CSS的支持較弱)。

4.有利於SEO:和搜索引擎建立良好溝通,有助於爬蟲抓取更多的有效信息:爬蟲依賴於標籤來確定上下文和各個關鍵字的權重。

5.便於團隊開發和維護,語義化更具可讀性,是下一步吧網頁的重要動向,遵循W3C標準的團隊都遵循這個標準,可以減少差異化。

4.你如何對網站的文件和資源進行優化?

期待的解決方案包括:文件合併文件最小化/文件壓縮使用CDN託管緩存的使用(多個域名來提供緩存)其他。

5.爲什麼利用多個域名來提供網站資源會更有效?

  • 1.CDN緩存更方便

  • 2.突破瀏覽器併發限制(一般每個域名建立的鏈接不超過6個)

  • 3.Cookieless,節省帶寬,尤其是上行帶寬一般比下行要慢

  • 4.對於UGC的內容和主站隔離,防止不必要的安全問題(上傳js竊取主站cookie之類的)。正是這個原因要求用戶內容的域名必須不是自己主站的子域名,而是一個完全獨立的第三方域名。

  • 5.數據做了劃分,甚至切到了不同的物理集羣,通過子域名來分流比較省事。這個可能被用的不多。 
    PS:關於Cookie的問題,帶寬是次要的,安全隔離纔是主要的。關於多域名,也不是越多越好,雖然服務器端可以做泛解釋,瀏覽器做dns解釋也是耗時間的,而且太多域名,如果要走https的話,還有要多買證書和部署的問題。

6.請說出三種減少頁面加載時間的方法。(加載時間指感知的時間或者實際加載時間)

  • 1.優化圖片

  • 2.圖像格式的選擇(GIF:提供的顏色較少,可用在一些對顏色要求不高的地方)

  • 3.優化CSS(壓縮合並css,如margin-top,margin-left…)

  • 4.網址後加斜槓(如www.campr.com/目錄,會判斷這個“目錄是什麼文件類型,或者是目錄。)

  • 5.標明高度和寬度(如果瀏覽器沒有找到這兩個參數,它需要一邊下載圖片一邊計算大小,如果圖片很多,瀏覽器需要不斷地調整頁面。這不但影響速度,也影響瀏覽體驗。當瀏覽器知道了高度和寬度參數後,即使圖片暫時無法顯示,頁面上也會騰出圖片的空位,然後繼續加載後面的內容。從而加載時間快了,瀏覽體驗也更好了。)

  • 6.減少http請求(合併文件,合併圖片)。

7.如果你參與到一個項目中,發現他們使用Tab來縮進代碼,但是你喜歡空格,你會怎麼做?

建議這個項目使用像EditorConfig(http://editorconfig.org/)之類的規範 
爲了保持一致性,接受項目原有的風格 
直接使用VIM的retab命令

8.請寫一個簡單的幻燈效果頁面

如果不使用JS來完成,可以加分。(如:純CSS實現的幻燈片效果)

9.你都使用哪些工具來測試代碼的性能?

Profiler,JSPerf(http://jsperf.com/nexttick-vs-setzerotimeout-vs-settimeout),Dromaeo。

10.如果今年你打算熟練掌握一項新技術,那會是什麼?

nodejs,html5,css3,less等。

11.請談一下你對網頁標準和標準制定機構重要性的理解。

w3c存在的意義就是讓瀏覽器兼容性問題儘量小,首先是他們對瀏覽器開發者的約束,然後是對開發者的約束。

12.什麼是FOUC(無樣式內容閃爍)?你如何來避免FOUC?

FOUC(Flash Of Unstyled Content)–文檔樣式閃爍

而引用CSS文件的@import就是造成這個問題的罪魁禍首。IE會先加載整個HTML文檔的DOM,然後再去導入外部的CSS文件,因此,在頁面DOM加載完成到CSS導入完成中間會有一段時間頁面上的內容是沒有樣式的,這段時間的長短跟網速,電腦速度都有關係。解決方法簡單的出奇,只要在之間加入一個或者<script>元素就可以了。

13.doctype(文檔類型)的作用是什麼?你知道多少種文檔類型?

此標籤可告知瀏覽器文檔使用哪種HTML或XHTML規範。該標籤可聲明三種DTD類型,分別表示嚴格版本、過渡版本以及基於框架的HTML文檔。

HTML 4.01規定了三種文檔類型:Strict、Transitional以及Frameset。

XHTML 1.0規定了三種XML文檔類型:Strict、Transitional以及Frameset。

Standards(標準)模式(也就是嚴格呈現模式)用於呈現遵循最新標準的網頁,而Quirks(包容)模式(也就是鬆散呈現模式或者兼容模式)用於呈現爲傳統瀏覽器而設計的網頁。

14.瀏覽器標準模式和怪異模式之間的區別是什麼?

W3C標準推出以後,瀏覽器都開始採納新標準,但存在一個問題就是如何保證舊的網頁還能繼續瀏覽,在標準出來以前,很多頁面都是根據舊的渲染方法編寫的,如果用的標準來渲染,將導致頁面顯示異常。爲保持瀏覽器渲染的兼容性,使以前的頁面能夠正常瀏覽,瀏覽器都保留了舊的渲染方法(如:微軟的IE)。這樣瀏覽器渲染上就產生了Quircks mode和Standars mode,兩種渲染方法共存在一個瀏覽器上。IE盒子模型和標準W3C盒子模型:ie的width包括:padding\border。標準的width不包括:padding\border

在js中如何判斷當前瀏覽器正在以何種方式解析? 
document對象有個屬性compatMode,它有兩個值:BackCompat對應quirks mode,CSS1Compat對應strict mode。

15.使用XHTML的侷限有哪些?

XHTML 與HTML的區別爲:

  • XHTML 元素必須被正確地嵌套。

  • XHTML 元素必須被關閉。

  • 標籤名必須用小寫字母。

  • XHTML 文檔必須擁有根元素。 
    侷限:

所有的 XHTML 元素都必須被正確地嵌套,XHTML 必須擁有良好的結構,所有的標籤必須小寫,並且所有的 XHTML 元素必須被關閉。所有的 XHTML 文檔必須擁有 DOCTYPE 聲明,並且 html、head、title 和 body 元素必須存在。雖然代碼更加的優雅,但缺少容錯性,不利於快速開發。

16.如果網頁內容需要支持多語言,你會怎麼做?

下面這些問題需要考慮:

  • 應用字符集的選擇,選擇UTF-8編碼

  • 語言書寫習慣&導航結構

  • 數據庫驅動型網站

17.data-屬性的作用是什麼?

data-* 屬性用於存儲頁面或應用程序的私有自定義數據。data-* 屬性賦予我們在所有 HTML 元素上嵌入自定義 data 屬性的能力。存儲的(自定義)數據能夠被頁面的 JavaScript 中利用,以創建更好的用戶體驗(不進行 Ajax 調用或服務器端數據庫查詢)。

data-* 屬性包括兩部分:

  • 屬性名不應該包含任何大寫字母,並且在前綴 “data-” 之後必須有至少一個字符

  • 屬性值可以是任意字符串

18.如果把HTML5看作做一個開放平臺,那它的構建模塊有哪些?

<nav>,<header>,<section>,<footer>等。

19.請描述一下cookies,sessionStorage和localStorage的區別?

sessionStorage和localStorage是HTML5 Web Storage API提供的,可以方便的在web請求之間保存數據。有了本地數據,就可以避免數據在瀏覽器和服務器間不必要地來回傳遞。sessionStorage、localStorage、cookie都是在瀏覽器端存儲的數據,其中sessionStorage的概念很特別,引入了一個“瀏覽器窗口”的概念。sessionStorage是在同源的同窗口(或tab)中,始終存在的數據。也就是說只要這個瀏覽器窗口沒有關閉,即使刷新頁面或進入同源另一頁面,數據仍然存在。關閉窗口後,sessionStorage即被銷燬。同時“獨立”打開的不同窗口,即使是同一頁面,sessionStorage對象也是不同的cookies會發送到服務器端。其餘兩個不會。Microsoft指出InternetExplorer8增加cookie限制爲每個域名50個,但IE7似乎也允許每個域名50個cookie。

  • Firefox每個域名cookie限制爲50個。

  • Opera每個域名cookie限制爲30個。

  • Firefox和Safari允許cookie多達4097個字節,包括名(name)、值(value)和等號。

  • Opera允許cookie多達4096個字節,包括:名(name)、值(value)和等號。

  • InternetExplorer允許cookie多達4095個字節,包括:名(name)、值(value)和等號。

20.描述下“reset”CSS文件的作用和使用它的好處。

因爲瀏覽器的品種很多,每個瀏覽器的默認樣式也是不同的,所以定義一個css reset可以使各瀏覽器的默認樣式統一。

21.解釋下浮動和它的工作原理。

關於浮動我們需要了解,浮動的框可以向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框爲止。要想使元素浮動,必須爲元素設置一個寬度(width)。雖然浮動元素不是文檔流之中,但是它浮動後所處的位置依然是在浮動之前的水平方向上。由於浮動框不在文檔的普通流中,所以文檔的普通流中的塊框表現得就像浮動框不存在一樣,下面的元素填補原來的位置。有些元素會在浮動元素的下方,但是這些元素的內容並不一定會被浮動的元素所遮蓋,對內聯元素進行定位時,這些元素會考慮浮動元素的邊界,會圍繞着浮動元素放置。也可以把浮動元素想象成是被塊元素忽略的元素,而內聯元素會關注浮動元素的。

22.列舉不同的清除浮動的技巧,並指出它們各自適用的使用場景。

  • 1.使用空標籤清除浮動。這種方法是在所有浮動標籤後面添加一個空標籤定義css clear:both.弊端就是增加了無意義標籤。

  • 2.使用overflow。給包含浮動元素的父標籤添加css屬性overflow:auto;zoom:1;zoom:1用於兼容IE6。

  • 3.使用after僞對象清除浮動。該方法只適用於非IE瀏覽器。具體寫法可參照以下示例。使用中需注意以下幾點。一、該方法中必須爲需要清除浮動元素的僞對象中設置height:0,否則該元素會比實際高出若干像素;二、content屬性是必須的,但其值可以爲空,content屬性的值設爲”.”,空亦是可以的。

  • 4.浮動外部元素 
    此三種方法各有利弊,使用時應擇優選擇,比較之下第二種方法更爲可取。

23.解釋下CSS sprites,以及你要如何在頁面或網站中使用它。

CSS Sprites其實就是把網頁中一些背景圖片整合到一張圖片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的組合進行背景定位,background-position可以用數字能精確的定位出背景圖片的位置。

24.你最喜歡的圖片替換方法是什麼,你如何選擇使用。

<h2><span圖片丟這裏></span>Hello World</h2>

把span背景設成文字內容,這樣又可以保證seo,也有圖片的效果在上面。一般都是:alt,title,onerror。

25.討論CSS hacks,條件引用或者其他。

各個瀏覽器都認識,這裏給firefox用;

background-color:red\9;\9所有的ie瀏覽器可識別;

background-color:yellow\0;\0是留給ie8的+background-color:pink;+ie7定了;

_background-color:orange;_專門留給神奇的ie6;:root#test{background-color:purple\9;}:root是給ie9的,

@media all and(min-width:0px){#test{background-color:black\0;}}這個是老是跟ie搶着認\0的神奇的opera,必須加個\0,不然firefox,chrome,safari也都認識。

@media screen and(-webkit-min-device-pixel-ratio:0){#test{background-color:gray;}}最後這個是瀏覽器新貴chrome和safari的。

26.如何爲有功能限制的瀏覽器提供網頁?你會使用哪些技術和處理方法?

27.如何視覺隱藏網頁內容,只讓它們在屏幕閱讀器中可用?

  • display:none;的缺陷搜索引擎可能認爲被隱藏的文字屬於垃圾信息而被忽略屏幕閱讀器(是爲視覺上有障礙的人設計的讀取屏幕內容的程序)會忽略被隱藏的文字。

  • visibility:hidden;的缺陷這個大家應該比較熟悉就是隱藏的內容會佔據他所應該佔據物理空間3.overflow:hidden;一個比較合理的方法.texthidden{display:block;/統一轉化爲塊級元素/overflow:hidden;width:0;height:0;}就像上面的一段CSS所展示的方法,將寬度和高度設定爲0,然後超過部分隱藏,就會彌補上述一、二方法中的缺陷,也達到了隱藏內容的目的。

28.你用過柵格系統嗎?如果使用過,你最喜歡哪種?

比如:Bootstrap,流式柵格系統,http://960.gs/,柵格系統延續美學。

29.你用過媒體查詢,或針對移動端的佈局/CSS嗎?

媒體查詢,就是響應式佈局。通過不同的媒介類型和條件定義樣式表規則。媒介查詢讓CSS可以更精確作用於不同的媒介類型和同一媒介的不同條件。

語法結構及用法:@media 設備名 only (選取條件) not (選取條件) and(設備選取條件),設備二{sRules}。

示例如下:

 /* 當瀏覽器的可視區域小於980px */

 @media screen and max-width 980px {

 #wrap {width: 90%; margin:0 auto;}

 #content {width: 60%;padding: 5%;}

 #sidebar {width: 30%;}

 #footer {padding: 8% 5%;margin-bottom: 10px;}

 }

 /* 當瀏覽器的可視區域小於650px */

 @media screen and max-width 650px {

#header {height: auto;}

#searchform {position: absolute;top: 5px;right: 0;}

#content {width: auto; float: none; margin: 20px 0;}

#sidebar {width: 100%; float: none; margin: 0;}

}

30.你熟悉SVG樣式的書寫嗎?

SVG 意爲可縮放矢量圖形(Scalable Vector Graphics)。

什麼是SVG?

  • SVG 指可伸縮矢量圖形 (Scalable Vector Graphics)

  • SVG 用來定義用於網絡的基於矢量的圖形

  • SVG 使用 XML 格式定義圖形

  • SVG 圖像在放大或改變尺寸的情況下其圖形質量不會有所損失

  • SVG 是萬維網聯盟的標準

  • SVG 與諸如 DOM 和 XSL 之類的 W3C 標準是一個整體 
    書寫示例如下:

<?xml version="1.0" standalone="no"?>

    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

    <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">

        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>

    </svg>

31.如何優化網頁的打印樣式?

<link rel = "stylesheet" type = "text/css" media = "screen" href = "xxx.css"/>

其中media指定的屬性就是設備,顯示器上就是screen,打印機則是print,電視是tv,投影儀是projection。打印樣式示例如下:

<link rel = "stylesheet" type = "text/css" media = "print" href = "yyy.css"/>

但打印樣式表也應注意以下事項:

  • 打印樣式表中最好不要用背景圖片,因爲打印機不能打印CSS中的背景。如要顯示圖片,請使用html插入到頁面中。

  • 最好不要使用像素作爲單位,因爲打印樣式表要打印出來的會是實物,所以建議使用pt和cm。

  • 隱藏掉不必要的內容。(@print div{display:none;})

  • 打印樣式表中最好少用浮動屬性,因爲它們會消失。如果想要知道打印樣式表的效果如何,直接在瀏覽器上選擇打印預覽就可以了。

32.在書寫高效CSS時會有哪些問題需要考慮?

  • 1.樣式是:從右向左的解析一個選擇器;

  • 2.ID最快,Universal最慢有四種類型的key selector,解析速度由快到慢依次是:ID、class、tag和universal ;

  • 3.不要tag-qualify(永遠不要這樣做ul#main-navigation{}ID已經是唯一的,不需要Tag來標識,這樣做會讓選擇器變慢。);

  • 4.後代選擇器最糟糕(換句話說,下面這個選擇器是很低效的:html body ul li a{});

  • 5.想清楚你爲什麼這樣寫;

  • 6.CSS3的效率問題(CSS3選擇器(比如:nth-child)能夠漂亮的定位我們想要的元素,又能保證我們的CSS整潔易讀。但是這些神奇的選擇器會浪費很多的瀏覽器資源。);

  • 7.我們知道#ID速度是最快的,那麼我們都用ID,是不是很快。但是我們不應該爲了效率而犧牲可讀性和可維護性。

33.使用CSS預處理器的優缺點有哪些?

 LESS&SassLESS是受Sass啓發而開發的工具,它列出瞭如下開發的理由:

 “爲什麼要開發一個Sass的替代品呢?原因很簡單:首先是語法。Sass的一個關鍵特性是縮進式的語法,這種語法可以產生柱式外觀的代碼。但是你需要花費時間學習一門新的語法以及重新構建你現在的樣式表。LESS給CSS帶來了很多特性,使得LESS能夠和CSS無縫地緊密結合在一起。因此,你可以平滑地由CSS遷移到LESS,如果你只是對使用變量或者操作感興趣的話,你不需要學習一整門全新的語言。”

  StylusStylus相對前兩者較新,可以看官方文檔介紹的功能。
  • 1.來自NodeJS社區,所以和NodeJS走得很近,與JavaScript聯繫非常緊密。還有專門JavaScript API:http://learnboost.github.io/stylus/docs/js.html;

  • 2.支持Ruby之類等等框架;

  • 3.更多更強大的支持和功能總結:Sass看起來在提供的特性上佔有優勢,但是LESS能夠讓開發者平滑地從現存CSS文件過渡到LESS,而不需要像Sass那樣需要將CSS文件轉換成Sass格式。Stylus功能上更爲強壯,和js聯繫更加緊密。

34.如果設計中使用了非標準的字體,你該如何去實現?

所謂的標準字體是多數機器上都會有的,或者即使沒有也可以由默認字體替代的字體。

方法:

  • 用圖片代替

  • web fonts在線字庫,如Google Webfonts,Typekit等等;http://www.chinaz.com/free/2012/0815/269267.shtml;

  • @font-face,Webfonts(字體服務例如:Google Webfonts,Typekit等等。)

35.解釋下瀏覽器是如何判斷元素是否匹配某個CSS選擇器?

從後往前判斷。瀏覽器先產生一個元素集合,這個集合往往由最後一個部分的索引產生(如果沒有索引就是所有元素的集合)。然後向上匹配,如果不符合上一個部分,就把元素從集合中刪除,直到真個選擇器都匹配完,還在集合中的元素就匹配這個選擇器了。舉個例子,有選擇器:

body.ready#wrapper>.lol233

先把所有class中有lol233的元素拿出來組成一個集合,然後上一層,對每一個集合中的元素,如果元素的parent id不爲#wrapper則把元素從集合中刪去。再向上,從這個元素的父元素開始向上找,沒有找到一個tagName爲body且class中有ready的元素,就把原來的元素從集合中刪去。至此這個選擇器匹配結束,所有還在集合中的元素滿足。大體就是這樣,不過瀏覽器還會有一些奇怪的優化。爲什麼從後往前匹配因爲效率和文檔流的解析方向。效率不必說,找元素的父親和之前的兄弟比遍歷所喲兒子快而且方便。關於文檔流的解析方向,是因爲現在的CSS,一個元素只要確定了這個元素在文檔流之前出現過的所有元素,就能確定他的匹配情況。應用在即使html沒有載入完成,瀏覽器也能根據已經載入的這一部分信息完全確定出現過的元素的屬性。爲什麼是用集合主要也還是效率。基於CSS Rule數量遠遠小於元素數量的假設和索引的運用,遍歷每一條CSS Rule通過集合篩選,比遍歷每一個元素再遍歷每一條Rule匹配要快得多。

36.解釋一下你對盒模型的理解,以及如何在CSS中告訴瀏覽器使用不同的盒模型來渲染你的佈局。

關於盒模型請看文章CSS之佈局與定位。

請解釋一下*{box-sizing:border-box;}的作用,並且說明使用它有什麼好處? 
說到IE的bug,在IE6以前的版本中,IE對盒模型的解析出現一些問題,跟其它瀏覽器不同,將border與padding都包含在width之內。而另外一些瀏覽器則與它相反,是不包括border和padding的。

在我們開發的過程中會發現,有時候,如果對頁面中的大區域進行設置時,將border、padding計算到width和height之內,反而更靈活。但W3C的CSS2.1規範卻規定了他們並不能被包含其中。考慮到這個問題,css3中引入了一個新的屬性:box-sizing,它具有“content-box”和”border-box“兩個值。

box-sizing:content-box

當我們設置box-sizing:content-box;時,瀏覽器對盒模型的解釋遵從我們之前認識到的W3C標準,當它定義width和height時,它的寬度不包括border和padding。

box-sizing:border-box

當我們設置box-sizing:border-box;時,瀏覽器對盒模型的解釋與IE6之前的版本相同,當它定義width和height時,border和padding則是被包含在寬高之內的。內容的寬和高可以通過定義的“width”和“height”減去相應方向的“padding”和“border”的寬度得到。內容的寬和高必須保證不能爲負,必要時將自動增大該元素border box的尺寸以使其內容的寬或高最小爲0。

37.請羅列出你所知道的display屬性的全部值。

display屬性的值列表如下:

38.請解釋一下relative、fixed、absolute和static元素的區別?請解釋一下inline和inline-block的區別?

  • 關於第一個問題請看文章CSS之佈局與定位 。 
    inline:此元素會被顯示爲內聯元素,元素前後沒有換行符。

inline-block:行內塊元素。

39.你目前在使用哪一套CSS框架,或者在產品線上使用過哪一套?(Bootstrap,PureCSS,Foundation等等)

如果有,請問是哪一套?如果可以,你如何改善CSS框架? 
請問你有使用過CSS Flexbox或者Grid specs嗎?如果有,請問在性能和效率的方面你是怎麼看的?

40.解釋下事件代理。

JavaScript事件代理則是一種簡單的技巧,通過它你可以把事件處理器添加到一個父級元素上,這樣就避免了把事件處理器添加到多個子級元素上。當我們需要對很多元素添加事件的時候,可以通過將事件添加到它們的父節點而將事件委託給父節點來觸發處理函數。這主要得益於瀏覽器的事件冒泡機制。事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標元素。

function getEventTarget(e) {

    e=e||window.event;

    return e.target||e.srcElement;

}

41.解釋下JavaScript中this是如何工作的。

this永遠指向函數運行時所在的對象,而不是函數被創建時所在的對象。匿名函數或不處於任何對象中的函數指向window 。

  • 1.如果是call,apply,with,指定的this是誰,就是誰。

  • 2.普通的函數調用,函數被誰調用,this就是誰。

42.解釋下原型繼承的原理。

以下代碼展示了JS引擎如何查找屬性:

function getProperty(obj,prop) {

    if (obj.hasOwnProperty(prop)) {

        return obj[prop];

    } else if (obj.__proto__!==null) {

        return getProperty(obj.__proto__,prop);

    } else {

        return undefined;

    }

}

下圖展示的原(prototype)的關聯:

43.你是如何測試JavaScript代碼的?

結合自己的項目經驗進行講述。(chrome使用技巧)

44.AMD vs.CommonJS?

請看文章JavaScript之模塊化編程

45.什麼是哈希表?

散列表(也叫哈希表),是根據關鍵碼值直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。

46.解釋下爲什麼接下來這段代碼不是IIFE(立即調用的函數表達式):function foo(){}();.

  • 要做哪些改動使它變成IIFE? 
    因爲在解析器解析全局的function或者function內部function關鍵字的時候,默認是認爲function聲明,而不是function表達式,如果你不顯示告訴編譯器,它默認會聲明成一個缺少名字的function,並且拋出一個語法錯誤信息,因爲function聲明需要一個名字。

var foo = function() {

    // doSomeThing.

};

 

foo();

47.描述以下變量的區別:null,undefined或undeclared?

JavaScript的最初版本是這樣區分的:null是一個表示”無”的對象,轉爲數值時爲0;undefined是一個表示”無”的原始值,轉爲數值時爲NaN。

但是,上面這樣的區分,在實踐中很快就被證明不可行。目前,null和undefined基本是同義的,只有一些細微的差別。

null表示”沒有對象”,即該處不應該有值。典型用法是:

  • 用來初始化一個變量,這個變量可能被賦值爲一個對象。

  • 用來和一個已經初始化的變量比較,這個變量可以是也可以不是一個對象。

  • 當函數的參數期望是對象時,被用作參數傳入。

  • 當函數的返回值期望是對象時,被用作返回值傳出。

  • 作爲對象原型鏈的終點。 
    undefined表示”缺少值”,就是此處應該有一個值,但是還沒有定義。典型用法是:

  • 變量被聲明瞭,但沒有賦值時,就等於undefined。

  • 調用函數時,應該提供的參數沒有提供,該參數等於undefined。

  • 對象沒有賦值的屬性,該屬性的值爲undefined。

  • 函數沒有返回值時,默認返回undefined。 
    該如何檢測它們?

null:表示無值;undefined:表示一個未聲明的變量,或已聲明但沒有賦值的變量,或一個並不存在的對象屬性。

==運算符將兩者看作相等。如果要區分兩者,要使用===或typeof運算符。

以下是不正確的用法:

var exp = undefined;

 

if (exp == undefined) {

    alert("undefined");

}

exp爲null時,也會得到與undefined相同的結果,雖然null和undefined不一樣。注意:要同時判斷undefined和null時可使用本法。

typeof返回的是字符串,有六種可能:”number”、”string”、”boolean”、”object”、”function”、”undefined”。

以下是正確的用法:

var exp = undefined;

 

if(typeof(exp) == undefined) {

    alert("undefined");

}

JS中如何判斷null?

以下是不正確的用法:

var exp = null;

 

if(exp == null) {

    alert("is null");

}

exp爲undefined時,也會得到與null相同的結果,雖然null和undefined不一樣。注意:要同時判斷null和undefined時可使用本法。

var exp=null;

 

if(!exp) {

    alert("is null");

}

如果exp爲undefined或者數字零,也會得到與null相同的結果,雖然null和二者不一樣。注意:要同時判斷null、undefined和數字零時可使用本法。

var exp = null;

 

if(typeof(exp) == "null") {

    alert("is null");

}

爲了向下兼容,exp爲null時,typeof總返回object。這種方式也不太好。

以下是正確的用法:

var exp = null;

 

if(!exp&&typeof(exp) != "undefined" && exp != 0) {

    alert("is null");

}

48.什麼是閉包,如何使用它,爲什麼要使用它?

包就是能夠讀取其他函數內部變量的函數。由於在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成“定義在一個函數內部的函數”。

所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋樑。閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。

使用閉包的注意點:

  • 由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。

  • 閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。 
    (關於閉包,詳細瞭解請看JavaScript之作用域與閉包詳解)

49.請舉出一個匿名函數的典型用例?

自執行函數,用閉包模擬私有變量、特權函數等。

50.解釋“JavaScript模塊模式”以及你在何時使用它。

 如果有提到無污染的命名空間,可以考慮加分。

如果你的模塊沒有自己的命名空間會怎麼樣? 
請看文章-JavaScript之模塊化編程 和JavaScript之命名空間模式 淺析

51.你是如何組織自己的代碼?是使用模塊模式,還是使用經典繼承的方法?

請看文章-JavaScript之模塊化編程和Javascript之對象的繼承

52.請指出JavaScript宿主對象和原生對象的區別?

原生對象

ECMA-262 把本地對象(native object)定義爲“獨立於宿主環境的 ECMAScript 實現提供的對象”。

“本地對象”包含哪些內容:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。

由此可以看出,簡單來說,本地對象就是 ECMA-262 定義的類(引用類型)。

內置對象

ECMA-262 把內置對象(built-in object)定義爲“由 ECMAScript 實現提供的、獨立於宿主環境的所有對象,在 ECMAScript 程序開始執行時出現”。這意味着開發者不必明確實例化內置對象,它已被實例化了。

同樣是“獨立於宿主環境”。根據定義我們似乎很難分清“內置對象”與“本地對象”的區別。而ECMA-262 只定義了兩個內置對象,即 Global 和 Math (它們也是本地對象,根據定義,每個內置對象都是本地對象)。如此就可以理解了。內置對象是本地對象的一種。

宿主對象

何爲“宿主對象”?主要在這個“宿主”的概念上,ECMAScript中的“宿主”當然就是我們網頁的運行環境,即“操作系統”和“瀏覽器”。

所有非本地對象都是宿主對象(host object),即由 ECMAScript 實現的宿主環境提供的對象。所有的BOM和DOM都是宿主對象。因爲其對於不同的“宿主”環境所展示的內容不同。其實說白了就是,ECMAScript官方未定義的對象都屬於宿主對象,因爲其未定義的對象大多數是自己通過ECMAScript程序創建的對象。

53.call和.apply的區別是什麼?

call方法: 
語法:call(thisObj,Object) 
定義:調用一個對象的一個方法,以另一個對象替換當前對象。 
說明:call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變爲由 thisObj 指定的新對象。 如果沒有提供 thisObj 參數,那麼 Global 對象被用作 thisObj。 
apply方法: 
語法:apply(thisObj,[argArray]) 
定義:應用某一對象的一個方法,用另一個對象替換當前對象。 
說明:如果 argArray 不是一個有效的數組或者不是 arguments 對象,那麼將導致一個 TypeError。如果沒有提供 argArray 和 thisObj 任何一個參數,那麼 Global 對象將被用作 thisObj, 並且無法被傳遞任何參數。

對於apply和call兩者在作用上是相同的,但兩者在參數上有以下區別: 
對於第一個參數意義都一樣,但對第二個參數:apply傳入的是一個參數數組,也就是將多個參數組合成爲一個數組傳入,而call則作爲call的參數傳入(從第二個參數開始)。如 func.call(func1,var1,var2,var3)對應的apply寫法爲:func.apply(func1,[var1,var2,var3])同時使用apply的好處是可以直接將當前函數的arguments對象作爲apply的第二個參數傳入。

54.請解釋Function.prototype.bind的作用?

55.你何時優化自己的代碼?

請看文章JavaScript之高效編程 及JavaScript編碼風格指南。

56.你能解釋一下JavaScript中的繼承是如何工作的嗎?

原型鏈等。

57.在什麼時候你會使用document.write()?

大多數生成的廣告代碼依舊使用document.write(),雖然這種用法會讓人很不爽。

58.請指出瀏覽器特性檢測,特性推斷和瀏覽器UA字符串嗅探的區別?

特性檢測:爲特定瀏覽器的特性進行測試,並僅當特性存在時即可應用特性。

User-Agent檢測:最早的瀏覽器嗅探即用戶代理檢測,服務端(以及後來的客戶端)根據UA字符串屏蔽某些特定的瀏覽器查看網站內容。

特性推斷:嘗試使用多個特性但僅驗證了其中之一。根據一個特性的存在推斷另一個特性是否存在。問題是,推斷是假設並非事實,而且可能導致可維護性的問題。

59.請儘可能詳盡的解釋AJAX的工作原理。

請參考文章AJAX工作原理。

60.請解釋JSONP的工作原理,以及它爲什麼不是真正的AJAX。

JSONP (JSON with Padding)是一個簡單高效的跨域方式,HTML中的script標籤可以加載並執行其他域的javascript,於是我們可以通過script標記來動態加載其他域的資源。例如我要從域A的頁面pageA加載域B的數據,那麼在域B的頁面pageB中我以JavaScript的形式聲明pageA需要的數據,然後在 pageA中用script標籤把pageB加載進來,那麼pageB中的腳本就會得以執行。JSONP在此基礎上加入了回調函數,pageB加載完之後會執行pageA中定義的函數,所需要的數據會以參數的形式傳遞給該函數。JSONP易於實現,但是也會存在一些安全隱患,如果第三方的腳本隨意地執行,那麼它就可以篡改頁面內容,截獲敏感數據。但是在受信任的雙方傳遞數據,JSONP是非常合適的選擇。

AJAX是不跨域的,而JSONP是一個是跨域的,還有就是二者接收參數形式不一樣!

61.你使用過JavaScript模板系統嗎?

如有使用過,請談談你都使用過哪些庫,比如Mustache.js,Handlebars等等。

62.請解釋變量聲明提升。

在JS裏定義的變量,存在於作用域鏈裏,而在函數執行時會先把變量的聲明進行提升,僅僅是把聲明進行了提升,而其值的定義還在原來位置。示例如下:

var test = function() {

    console.log(name); // 輸出:undefined

    var name = "jeri";

    console.log(name); // 輸出:jeri

}

 

test();

上述代碼與下述代碼等價。

var test = function() {

    var name;

    console.log(name); // 輸出:undefined

    name = "jeri";

    console.log(name); // 輸出:jeri

}

 

test();

由以上代碼可知,在函數執行時,把變量的聲明提升到了函數頂部,而其值定義依然在原來位置。

63.請描述下事件冒泡機制。

冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發。

捕獲型事件:事件從最不精確的對象(document 對象)開始觸發,然後到最精確(也可以在窗口級別捕獲事件,不過必須由開發人員特別指定)。

支持W3C標準的瀏覽器在添加事件時用addEventListener(event,fn,useCapture)方法,基中第3個參數useCapture是一個Boolean值,用來設置事件是在事件捕獲時執行,還是事件冒泡時執行。而不兼容W3C的瀏覽器(IE)用attachEvent()方法,此方法沒有相關設置,不過IE的事件模型默認是在事件冒泡時執行的,也就是在useCapture等於false的時候執行,所以把在處理事件時把useCapture設置爲false是比較安全,也實現兼容瀏覽器的效果。

64.”attribute”和”property”的區別是什麼?

1.定義

Property:屬性,所有的HTML元素都由HTMLElement類型表示,HTMLElement類型直接繼承自Element並添加了一些屬性,添加的這些屬性分別對應於每個HTML元素都有下面的這5個標準特性: id,title,lang,dir,className。DOM節點是一個對象,因此,他可以和其他的JavaScript對象一樣添加自定義的屬性以及方法。property的值可以是任何的數據類型,對大小寫敏感,自定義的property不會出現在html代碼中,只存在js中。

Attribute:特性,區別於property,attribute只能是字符串,大小寫不敏感,出現在innerHTML中,通過類數組attributes可以羅列所有的attribute。

2.相同之處

標準的 DOM properties 與 attributes 是同步的。公認的(非自定義的)特性會被以屬性的形式添加到DOM對象中。如,id,align,style等,這時候操作property或者使用操作特性的DOM方法如getAttribute()都可以操作屬性。不過傳遞給getAttribute()的特性名與實際的特性名相同。因此對於class的特性值獲取的時候要傳入“class”。

3.不同之處

1).對於有些標準的特性的操作,getAttribute與點號(.)獲取的值存在差異性。如href,src,value,style,onclick等事件處理程序。 
2).href:getAttribute獲取的是href的實際值,而點號獲取的是完整的url,存在瀏覽器差異。

65.爲什麼擴展JavaScript內置對象不是好的做法?

66.爲什麼擴展JavaScript內置對象是好的做法?

67.請指出document.onload和document.ready兩個事件的區別。

頁面加載完成有兩種事件,一是ready,表示文檔結構已經加載完成(不包含圖片等非文字媒體文件),二是onload,指示頁面包含圖片等文件在內的所有元素都加載完成。

68.==和===有什麼不同?

首先,== equality 等同,=== identity 恆等。 ==, 兩邊值類型不同的時候,要先進行類型轉換,再比較。 ===,不做類型轉換,類型不同的一定不等。

先說 ===,這個比較簡單。下面的規則用來判斷兩個值是否===相等:

  • 如果類型不同,就[不相等]

  • 如果兩個都是數值,並且是同一個值,那麼[相等];(!例外)的是,如果其中至少一個是NaN,那麼[不相等]。(判斷一個值是否是NaN,只能用isNaN()來判斷)

  • 如果兩個都是字符串,每個位置的字符都一樣,那麼[相等];否則[不相等]。

  • 如果兩個值都是true,或者都是false,那麼[相等]。

  • 如果兩個值都引用同一個對象或函數,那麼[相等];否則[不相等]。

  • 如果兩個值都是null,或者都是undefined,那麼[相等]。 
    再說 ==,根據以下規則:

  • 如果兩個值類型相同,進行 === 比較。

  • 如果兩個值類型不同,他們可能相等。根據下面規則進行類型轉換再比較: 
    1.如果一個是null、一個是undefined,那麼[相等]。 
    2.如果一個是字符串,一個是數值,把字符串轉換成數值再進行比較。 
    3.如果任一值是 true,把它轉換成 1 再比較;如果任一值是 false,把它轉換成 0 再比較。 
    4.如果一個是對象,另一個是數值或字符串,把對象轉換成基礎類型的值再比較。對象轉換成基礎類型,利用它的toString或者valueOf方法。js核心內置類,會嘗試valueOf先於toString;例外的是Date,Date利用的是toString轉換。
    5.任何其他組合,都[不相等]。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章