一些面試題
1.你能描述一下漸進增強和優雅降級之間的不同嗎?
優雅降級:Web站點在所有新式瀏覽器中都能正常工作,如果使用者使用的是老式瀏覽器,則程式碼會檢查以確認它們是否能正常工作。由於IE獨特的盒模型佈局問題,針對不同版本的IE的hack實踐過優雅降級了,為那些無法支援功能的瀏覽器增加候選方案,使之在舊式瀏覽器上以某種形式降級體驗卻不至於完全失效.
漸進增強:從被所有瀏覽器支援的基本功能開始,逐步地新增那些只有新式瀏覽器才支援的功能,向頁面增加無害於基礎瀏覽器的額外樣式和功能的。當瀏覽器支援時,它們會自動地呈現出來併發揮作用。
2.執行緒與程序的區別
一個程式至少有一個程序,一個程序至少有一個執行緒。執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。
另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。
執行緒在執行過程中與程序還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程序的排程和管理以及資源分配。這就是程序和執行緒的重要區別。
3.說說你對語義化的理解?
- 1:去掉或樣式丟失的時候能讓頁面呈現清晰的結構:html本身是沒有表現的,我們看到例如<h1>是粗體,字型大小2em,加粗;<strong>是加粗的,不要認為這是html的表現,這些其實html預設的css樣式在起作用,所以去掉或樣式丟失的時候能讓頁面呈現清晰的結構不是語義化的HTML結構的優點,但是瀏覽器都有有預設樣式,預設樣式的目的也是為了更好的表達html的語義,可以說瀏覽器的預設樣式和語義化的HTML結構是不可分割的。
- 2.螢幕閱讀器(如果訪客有視障)會完全根據你的標記來“讀”你的網頁。
- 3.PDA、手機等裝置可能無法像普通電腦的瀏覽器一樣來渲染網頁(通常是因為這些裝置對CSS的支援較弱)。
- 4.
有利於SEO:和搜尋引擎建立良好溝通,有助於爬蟲抓取更多的有效資訊:爬蟲依賴於標籤來確定上下文和各個關鍵字的權重。
- 6.
便於團隊開發和維護,語義化更具可讀性,是下一步吧網頁的重要動向,遵循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.請寫一個簡單的幻燈效果頁面
如果不使用JS來完成,可以加分。(如:純CSS實現的幻燈片效果)
8.doctype(文件型別)的作用是什麼?你知道多少種文件型別?
此標籤可告知瀏覽器文件使用哪種HTML或XHTML規範。該標籤可宣告三種DTD型別,分別表示嚴格版本、過渡版本以及基於框架的HTML文件。
HTML4.01規定了三種文件型別:Strict、Transitional以及Frameset。
XHTML1.0規定了三種XML文件型別:Strict、Transitional以及Frameset。
Standards(標準)模式(也就是嚴格呈現模式)用於呈現遵循最新標準的網頁,而Quirks(包容)模式(也就是鬆散呈現模式或者相容模式)用於呈現為傳統瀏覽器而設計的網頁。
9.使用XHTML的侷限有哪些?
XHTML 與HTML的區別為:
- XHTML 元素必須被正確地巢狀。
- XHTML 元素必須被關閉。
- 標籤名必須用小寫字母。
- XHTML 文件必須擁有根元素。
侷限:
所有的 XHTML 元素都必須被正確地巢狀,XHTML 必須擁有良好的結構,所有的標籤必須小寫,並且所有的 XHTML 元素必須被關閉。所有的 XHTML 文件必須擁有 DOCTYPE 宣告,並且 html、head、title 和 body 元素必須存在。雖然程式碼更加的優雅,但缺少容錯性,不利於快速開發。
10.如果網頁內容需要支援多語言,你會怎麼做?
下面這些問題需要考慮:
- 應用字符集的選擇,選擇UTF-8編碼
- 語言書寫習慣&導航結構
- 資料庫驅動型網站
11、data-屬性的作用是什麼?
data-* 屬性用於儲存頁面或應用程式的私有自定義資料。data-* 屬性賦予我們在所有 HTML 元素上嵌入自定義 data 屬性的能力。儲存的(自定義)資料能夠被頁面的 JavaScript 中利用,以建立更好的使用者體驗(不進行 Ajax 呼叫或伺服器端資料庫查詢)。
data-* 屬性包括兩部分:
- 屬性名不應該包含任何大寫字母,並且在字首 "data-" 之後必須有至少一個字元
- 屬性值可以是任意字串
12.請描述一下cookies,sessionStorage和localStorage的區別?
sessionStorage和localStorage是HTML5WebStorageAPI提供的,可以方便的在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)和等號。。
13.解釋下浮動和它的工作原理。
關於浮動我們需要了解,浮動的框可以向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止。要想使元素浮動,必須為元素設定一個寬度(width)。雖然浮動元素不是文件流之中,但是它浮動後所處的位置依然是在浮動之前的水平方向上。由於浮動框不在文件的普通流中,所以文件的普通流中的塊框表現得就像浮動框不存在一樣,下面的元素填補原來的位置。有些元素會在浮動元素的下方,但是這些元素的內容並不一定會被浮動的元素所遮蓋,對內聯元素進行定位時,這些元素會考慮浮動元素的邊界,會圍繞著浮動元素放置。也可以把浮動元素想象成是被塊元素忽略的元素,而內聯元素會關注浮動元素的。
14.列舉不同的清除浮動的技巧,並指出它們各自適用的使用場景。
- 1.使用空標籤清除浮動。這種方法是在所有浮動標籤後面新增一個空標籤定義cssclear:both.弊端就是增加了無意義標籤。
- 2.使用overflow。給包含浮動元素的父標籤新增css屬性overflow:auto;zoom:1;zoom:1用於相容IE6。
- 3.使用after偽物件清除浮動。該方法只適用於非IE瀏覽器。具體寫法可參照以下示例。使用中需注意以下幾點。一、該方法中必須為需要清除浮動元素的偽物件中設定height:0,否則該元素會比實際高出若干畫素;二、content屬性是必須的,但其值可以為空,content屬性的值設為”.”,空亦是可以的。
- 4.浮動外部元素
此三種方法各有利弊,使用時應擇優選擇,比較之下第二種方法更為可取。
15.你用過柵格系統嗎?如果使用過,你最喜歡哪種?
比如:Bootstrap,流式柵格系統,http://960.gs/,柵格系統延續美學。
16.你用過媒體查詢,或針對移動端的佈局/CSS嗎?
媒體查詢,就是響應式佈局。通過不同的媒介型別和條件定義樣式表規則。媒介查詢讓CSS可以更精確作用於不同的媒介型別和同一媒介的不同條件。
語法結構及用法:@media 裝置名 only (選取條件) not (選取條件) and(裝置選取條件),裝置二{sRules}。
示例如下:
1 /* 當瀏覽器的可視區域小於980px */ 2 @media screen and (max-width: 980px) { 3 #wrap {width: 90%; margin:0 auto;} 4 #content {width: 60%;padding: 5%;} 5 #sidebar {width: 30%;} 6 #footer {padding: 8% 5%;margin-bottom: 10px;} 7 } 8 /* 當瀏覽器的可視區域小於650px */ 9 @media screen and (max-width: 650px) { 10 #header {height: auto;} 11 #searchform {position: absolute;top: 5px;right: 0;} 12 #content {width: auto; float: none; margin: 20px 0;} 13 #sidebar {width: 100%; float: none; margin: 0;} 14 }
17.如何優化網頁的列印樣式?
<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。
- 隱藏掉不必要的內容。(@printdiv{display:none;})
- 列印樣式表中最好少用浮動屬性,因為它們會消失。如果想要知道列印樣式表的效果如何,直接在瀏覽器上選擇列印預覽就可以了。
18.在書寫高效CSS時會有哪些問題需要考慮?
- 1.樣式是:從右向左的解析一個選擇器;
- 2.ID最快,Universal最慢有四種類型的keyselector,解析速度由快到慢依次是:ID、class、tag和universal ;
- 3.不要tag-qualify(永遠不要這樣做ul#main-navigation{}ID已經是唯一的,不需要Tag來標識,這樣做會讓選擇器變慢。);
- 4.後代選擇器最糟糕(換句話說,下面這個選擇器是很低效的:htmlbodyullia{});
- 5.想清楚你為什麼這樣寫;
- 6.CSS3的效率問題(CSS3選擇器(比如:nth-child)能夠漂亮的定位我們想要的元素,又能保證我們的CSS整潔易讀。但是這些神奇的選擇器會浪費很多的瀏覽器資源。);
- 7.我們知道#ID速度是最快的,那麼我們都用ID,是不是很快。但是我們不應該為了效率而犧牲可讀性和可維護性。
19.使用CSS前處理器的優缺點有哪些?
LESS&SassLESS是受Sass啟發而開發的工具,它列出瞭如下開發的理由:
“為什麼要開發一個Sass的替代品呢?原因很簡單:首先是語法。Sass的一個關鍵特性是縮排式的語法,這種語法可以產生柱式外觀的程式碼。但是你需要花費時間學習一門新的語法以及重新構建你現在的樣式表。LESS給CSS帶來了很多特性,使得LESS能夠和CSS無縫地緊密結合在一起。因此,你可以平滑地由CSS遷移到LESS,如果你只是對使用變數或者操作感興趣的話,你不需要學習一整門全新的語言。”
StylusStylus相對前兩者較新,可以看官方文件介紹的功能。
- 1.來自NodeJS社群,所以和NodeJS走得很近,與JavaScript聯絡非常緊密。還有專門JavaScriptAPI:http://learnboost.github.io/stylus/docs/js.html;
- 2.支援Ruby之類等等框架;
- 3.更多更強大的支援和功能總結:Sass看起來在提供的特性上佔有優勢,但是LESS能夠讓開發者平滑地從現存CSS檔案過渡到LESS,而不需要像Sass那樣需要將CSS檔案轉換成Sass格式。Stylus功能上更為強壯,和js聯絡更加緊密。
19.解釋一下你對盒模型的理解,以及如何在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“兩個值。
1 box-sizing:content-box
當我們設定box-sizing:content-box;時,瀏覽器對盒模型的解釋遵從我們之前認識到的W3C標準,當它定義width和height時,它的寬度不包括border和padding。
1 box-sizing:border-box
當我們設定box-sizing:border-box;時,瀏覽器對盒模型的解釋與IE6之前的版本相同,當它定義width和height時,border和padding則是被包含在寬高之內的。內容的寬和高可以通過定義的“width”和“height”減去相應方向的“padding”和“border”的寬度得到。內容的寬和高必須保證不能為負,必要時將自動增大該元素borderbox的尺寸以使其內容的寬或高最小為0。
20.請列出你所知道的display屬性的全部值。
display屬性的值列表如下:
20.請解釋一下relative、fixed、absolute和static元素的區別?請解釋一下inline和inline-block的區別?
- 關於第一個問題請看文章CSS之佈局與定位。
inline:此元素會被顯示為內聯元素,元素前後沒有換行符。
inline-block:行內塊元素。
21.你目前在使用哪一套CSS框架,或者在產品線上使用過哪一套?(Bootstrap,PureCSS,Foundation等等)
- 如果有,請問是哪一套?如果可以,你如何改善CSS框架?
- 請問你有使用過CSSFlexbox或者Gridspecs嗎?如果有,請問在效能和效率的方面你是怎麼看的?
22.解釋下事件代理。
JavaScript事件代理則是一種簡單的技巧,通過它你可以把事件處理器新增到一個父級元素上,這樣就避免了把事件處理器新增到多個子級元素上。當我們需要對很多元素新增事件的時候,可以通過將事件新增到它們的父節點而將事件委託給父節點來觸發處理函式。這主要得益於瀏覽器的事件冒泡機制。事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標元素。
1 function getEventTarget(e) { 2 e=e||window.event; 3 return e.target||e.srcElement; 4 }
23.解釋下JavaScript中this是如何工作的。
this永遠指向函式執行時所在的物件,而不是函式被建立時所在的物件。匿名函式或不處於任何物件中的函式指向window 。
1.如果是call,apply,with,指定的this是誰,就是誰。
2.普通的函式呼叫,函式被誰呼叫,this就是誰。
24.解釋下原型繼承的原理。
以下程式碼展示了JS引擎如何查詢屬性:
1 function getProperty(obj,prop) { 2 if (obj.hasOwnProperty(prop)) { 3 return obj[prop]; 4 } else if (obj.__proto__!==null) { 5 return getProperty(obj.__proto__,prop); 6 } else { 7 return undefined; 8 } 9 }
下圖展示的原(prototype)的關聯:
25.描述以下變數的區別:null,undefined或undeclared?
JavaScript的最初版本是這樣區分的:null是一個表示"無"的物件,轉為數值時為0;undefined是一個表示"無"的原始值,轉為數值時為NaN。
但是,上面這樣的區分,在實踐中很快就被證明不可行。目前,null和undefined基本是同義的,只有一些細微的差別。
null表示"沒有物件",即該處不應該有值。典型用法是:
- 用來初始化一個變數,這個變數可能被賦值為一個物件。
- 用來和一個已經初始化的變數比較,這個變數可以是也可以不是一個物件。
- 當函式的引數期望是物件時,被用作引數傳入。
- 當函式的返回值期望是物件時,被用作返回值傳出。
- 作為物件原型鏈的終點。
undefined表示"缺少值",就是此處應該有一個值,但是還沒有定義。典型用法是:
- 變數被聲明瞭,但沒有賦值時,就等於undefined。
- 呼叫函式時,應該提供的引數沒有提供,該引數等於undefined。
- 物件沒有賦值的屬性,該屬性的值為undefined。
- 函式沒有返回值時,預設返回undefined。
該如何檢測它們?
null:表示無值;undefined:表示一個未宣告的變數,或已宣告但沒有賦值的變數,或一個並不存在的物件屬性。
==運算子將兩者看作相等。如果要區分兩者,要使用===或typeof運算子。
以下是不正確的用法:
1 var exp = undefined; 2 3 if (exp == undefined) { 4 alert("undefined"); 5 }
exp為null時,也會得到與undefined相同的結果,雖然null和undefined不一樣。注意:要同時判斷undefined和null時可使用本法。
typeof返回的是字串,有六種可能:"number"、"string"、"boolean"、"object"、"function"、"undefined"。
以下是正確的用法:
1 var exp = undefined; 2 3 if(typeof(exp) == undefined) { 4 alert("undefined"); 5 }
JS中如何判斷null?
以下是不正確的用法:
1 var exp = null; 2 3 if(exp == null) { 4 alert("is null"); 5 }
exp為undefined時,也會得到與null相同的結果,雖然null和undefined不一樣。注意:要同時判斷null和undefined時可使用本法。
1 var exp=null; 2 3 if(!exp) { 4 alert("is null"); 5 }
如果exp為undefined或者數字零,也會得到與null相同的結果,雖然null和二者不一樣。注意:要同時判斷null、undefined和數字零時可使用本法。
1 var exp = null; 2 3 if(typeof(exp) == "null") { 4 alert("is null"); 5 }
為了向下相容,exp為null時,typeof總返回object。這種方式也不太好。
以下是正確的用法:
1 var exp = null; 2 3 if(!exp&&typeof(exp) != "undefined" && exp != 0) { 4 alert("is null"); 5 }
26.什麼是閉包,如何使用它,為什麼要使用它?
包就是能夠讀取其他函式內部變數的函式。由於在Javascript語言中,只有函式內部的子函式才能讀取區域性變數,因此可以把閉包簡單理解成“定義在一個函式內部的函式”。
所以,在本質上,閉包就是將函式內部和函式外部連線起來的一座橋樑。閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函式內部的變數,另一個就是讓這些變數的值始終保持在記憶體中。
使用閉包的注意點:
- 由於閉包會使得函式中的變數都被儲存在記憶體中,記憶體消耗很大,所以不能濫用閉包,否則會造成網頁的效能問題,在IE中可能導致記憶體洩露。解決方法是,在退出函式之前,將不使用的區域性變數全部刪除。
- 閉包會在父函式外部,改變父函式內部變數的值。所以,如果你把父函式當作物件(object)使用,把閉包當作它的公用方法(PublicMethod),把內部變數當作它的私有屬性(privatevalue),這時一定要小心,不要隨便改變父函式內部變數的值。
(關於閉包,詳細瞭解請看JavaScript之作用域與閉包詳解)
27.請指出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程式建立的物件。
28.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的第二個引數傳入。。
29.你能解釋一下JavaScript中的繼承是如何工作的嗎?
原型鏈等。
30.在什麼時候你會使用document.write()?
大多數生成的廣告程式碼依舊使用document.write(),雖然這種用法會讓人很不爽。
31.請儘可能詳盡的解釋AJAX的工作原理。
請參考文章AJAX工作原理。
32.請解釋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是一個是跨域的,還有就是二者接收引數形式不一樣!
33.請解釋變數宣告提升。
在JS裡定義的變數,存在於作用域鏈裡,而在函式執行時會先把變數的宣告進行提升,僅僅是把宣告進行了提升,而其值的定義還在原來位置。示例如下:
1 var test = function() { 2 console.log(name); // 輸出:undefined 3 var name = "jeri"; 4 console.log(name); // 輸出:jeri 5 } 6 7 test();
上述程式碼與下述程式碼等價。
1 var test = function() { 2 var name; 3 console.log(name); // 輸出:undefined 4 name = "jeri"; 5 console.log(name); // 輸出:jeri 6 } 7 8 test();
由以上程式碼可知,在函式執行時,把變數的宣告提升到了函式頂部,而其值定義依然在原來位置。
34.請描述下事件冒泡機制。
冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document物件)的順序觸發。
捕獲型事件:事件從最不精確的物件(document 物件)開始觸發,然後到最精確(也可以在視窗級別捕獲事件,不過必須由開發人員特別指定)。
支援W3C標準的瀏覽器在新增事件時用addEventListener(event,fn,useCapture)方法,基中第3個引數useCapture是一個Boolean值,用來設定事件是在事件捕獲時執行,還是事件冒泡時執行。而不相容W3C的瀏覽器(IE)用attachEvent()方法,此方法沒有相關設定,不過IE的事件模型預設是在事件冒泡時執行的,也就是在useCapture等於false的時候執行,所以把在處理事件時把useCapture設定為false是比較安全,也實現相容瀏覽器的效果。
35.請指出document.onload和document.ready兩個事件的區別。
頁面載入完成有兩種事件,一是ready,表示文件結構已經載入完成(不包含圖片等非文字媒體檔案),二是onload,指示頁面包含圖片等檔案在內的所有元素都載入完成。
36.==和===有什麼不同?
首先,== equality 等同,=== identity 恆等。==, 兩邊值型別不同的時候,要先進行型別轉換,再比較。===,不做型別轉換,型別不同的一定不等。
先說 ===,這個比較簡單。下面的規則用來判斷兩個值是否===相等:
- 如果型別不同,就[不相等]
- 如果兩個都是數值,並且是同一個值,那麼[相等];(!例外)的是,如果其中至少一個是NaN,那麼[不相等]。(判斷一個值是否是NaN,只能用isNaN()來判斷)
- 如果兩個都是字串,每個位置的字元都一樣,那麼[相等];否則[不相等]。
- 如果兩個值都是true,或者都是false,那麼[相等]。
- 如果兩個值都引用同一個物件或函式,那麼[相等];否則[不相等]。
- 如果兩個值都是null,或者都是undefined,那麼[相等]。
再說 ==,根據以下規則:
- 如果兩個值型別相同,進行 === 比較。
- 如果兩個值型別不同,他們可能相等。根據下面規則進行型別轉換再比較:
- 如果一個是null、一個是undefined,那麼[相等]。
- 如果一個是字串,一個是數值,把字串轉換成數值再進行比較。
- 如果任一值是 true,把它轉換成 1 再比較;如果任一值是 false,把它轉換成 0 再比較。
- 如果一個是物件,另一個是數值或字串,把物件轉換成基礎型別的值再比較。物件轉換成基礎型別,利用它的toString或者valueOf方法。js核心內建類,會嘗試valueOf先於toString;例外的是Date,Date利用的是toString轉換。非js核心的物件,令說(比較麻煩,我也不大懂)
- 任何其他組合,都[不相等]。
37.你如何從瀏覽器的URL中獲取查詢字串引數。
以下函式把獲取一個key的引數。
1 function parseQueryString ( name ){ 2 name = name.replace(/[\[]/,"\\\["); 3 var regexS = "[\\?&]"+name+"=([^&#]*)"; 4 var regex = new RegExp( regexS ); 5 var results = regex.exec( window.location.href ); 6 7 if(results == null) { 8 return ""; 9 } else { 10 return results[1]; 11 } 12 }
38.請解釋一下JavaScript的同源策略。
在客戶端程式語言中,如javascript和 ActionScript,同源策略是一個很重要的安全理念,它在保證資料的安全性方面有著重要的意義。同源策略規定跨域之間的指令碼是隔離的,一個域的指令碼不能訪問和操作另外一個域的絕大部分屬性和方法。那麼什麼叫相同域,什麼叫不同的域呢?當兩個域具有相同的協議, 相同的埠,相同的host,那麼我們就可以認為它們是相同的域。同源策略還應該對一些特殊情況做處理,比如限制file協議下指令碼的訪問許可權。本地的HTML檔案在瀏覽器中是通過file協議開啟的,如果指令碼能通過file協議訪問到硬碟上其它任意檔案,就會出現安全隱患,目前IE8還有這樣的隱患。