- 前端和計算機相關知識
- CSS
- CSS3
- css居中的方式
- 請寫一個簡單的幻燈效果頁面
- 什么是無樣式內容閃爍?如何避免?
- display:none和visibility:hidden的區別
- 解釋浮動和工作原理
- 清除浮動
- 解釋CSS Sprits,以及你要如何使用?
- 你最喜歡的圖片替換方法是什么?你將如何使用?
- 討論CSS hacks, 條件引用或其他
- 如何為有功能限制的瀏覽器提供網頁
- 在書寫高效CSS時會有哪些問題需要考慮?
- 如何優化網頁的打印樣式?
- 描述下你曾經使用過的CSS 預處理的優缺點
- 如果設計中使用了非標准的字體, 你將如何實現?
- block, inline和inline-block的區別
- 有哪些隱藏內容的方法(同時還要保證屏幕閱讀器可用)
- CSS選擇器級別
- alt和title的區別
- 知道bfc嗎?
- 行內元素,塊級元素,空元素各有哪些?
- html
- jquery問題
-
一些編程題
- 匿名函數變量
- this指向
- 定時
-
js算法題
一、前端編程
1. 你能描述一下漸進增強和優雅降級之間的不同嗎?
答:
- 定義:
- 優雅降級(graceful degradation): 一開始就構建站點的完整功能,然后針對瀏覽器測試和修復
- 漸進增強(progressive enhancement): 一開始只構建站點的最少特性,然后不斷針對各瀏覽器追加功能。
- 都關注於同一網站在不同設備里不同瀏覽器下的表現程度
- 區別:
- “優雅降級”觀點認為應該針對那些最高級、最完善的瀏覽器來設計網站. 而將那些被認為“過時”或有功能缺失的瀏覽器下的測試工作安排在開發周期的最后階段,並把測試對象限定為主流瀏覽器(如 IE、Mozilla 等)的前一個版本。
- “漸進增強”觀點則認為應關注於內容本身。請注意其中的差別:我甚至連“瀏覽器”三個字都沒提。
- 理解:
- "優雅降級"就是首先完整地實現整個網站,包括其中的功能和效果. 然后再為那些無法支持所有功能的瀏覽器增加候選方案, 使之在舊式瀏覽器上以某種形式降級體驗卻不至於完全失效.
- "漸進增強"則是從瀏覽器支持的基本功能開始, 首先為所有設備准備好清晰且語義化的html及完整內容, 然后再以無侵入的方法向頁面增加無害於基礎瀏覽器的額外樣式和功能. 當瀏覽器升級時, 它們會自動呈現並發揮作用.
2. 瀏覽器兼容問題:
- 問題1 不同瀏覽器的標簽默認的外補丁和內補丁不同.
- 即隨便寫幾個標簽, 在不加樣式控制的情況下, 各自的margin和padding差異較大.
- 解決方法: CCS里: *{margin:0; padding:0}
- 問題2 塊屬性標簽float后,又有橫行的margin情況下,在IE6顯示margin比設置的大
- 會使得ie6后面的一塊被頂到下一行.
- 解決方案: 在float的標簽樣式中加入 display: inline; 將其轉化為行內屬性
- 問題3 設置較小高度標簽(一般小於10px),在IE6,IE7,遨游中高度超出自己設置高度
- IE6、7和遨游里這個標簽的高度不受控制,超出自己設置的高度
- 解決方案: 給超出高度的標簽設置overflow:hidden;或者設置行高line-height 小於你設置的高度
- 原因: ie8之前的瀏覽器都會給標簽一個最小默認的行高的高度. 即使標簽是空的,這個標簽的高度還是會達到默認的行高.
- 問題4 行內屬性標簽,設置display:block后采用float布局,又有橫行的margin的情況,IE6間距bug
- 解決: 在display:block;后面加入display:inline;display:table;
- 問題5 圖片默認有間距
- 幾個img標簽放在一起的時候,有些瀏覽器會有默認的間距,加了問題一中提到的通配符也不起作用。
- 解決: 使用float屬性為img布局
- 問題6 標簽最低高度設置min-height不兼容
- 因為min-height本身就是一個不兼容的CSS屬性,所以設置min-height時不能很好的被各個瀏覽器兼容
- 如果我們要設置一個標簽的最小高度200px,需要進行的設置為:{min-height:200px; height:auto !important; height:200px; overflow:visible;}
- 問題7 透明度的兼容CSS設置
- 使用hacker
- IE6認識的hacker是下划線_和*
- IE7,遨游認識的hacker是*
- 使用hacker
- 問題8 IE ol的序號全為1, 不遞增
- 解決: li設置樣式{display: list-item}
問題9
ie6,7不支持display:inline-block
- 解決方法: 設置inline並觸法haslayout
- display:inline-block; *display:inline; *zoom:1
參考自: 常見瀏覽器兼容性問題與解決方案
3. 如何對網站的文件和資源進行優化?
答:
- 文件合並(同上題“假若你有5個不同的 CSS 文件, 加載進頁面的最好方式是?”)
- 減少調用其他頁面、文件的數量。一般我們為了讓頁面生動活潑會大量使用background來加載背景圖,而每個 background的圖像都會產生1次HTTP請求,要改善這個狀況,可以采用css的1個有用的background-position屬 性來加載背景圖,我們將需要頻繁加載的多個圖片合成為1個單獨的圖片,需要加載時可以采用:background:url(....) no-repeat x-offset y-offset;的形式加載即可將這部分圖片加載的HTTP請求縮減為1個。
- 每個http請求都會產生一次從你的瀏覽器到服務器端網絡往返過程,並且導致推遲到達服務器端和返回瀏覽器端的時間,我們稱之為延遲。
- 文件最小化/文件壓縮
- 即將需要傳輸的內容壓縮后傳輸到客戶端再解壓,這樣在網絡上傳輸的 數據量就會大幅減小。通常在服務器上的Apache、Nginx可以直接開啟這個設置,也可以從代碼角度直接設置傳輸文件頭,增加gzip的設置,也可以 從 負載均衡設備直接設置。不過需要留意的是,這個設置會略微增加服務器的負擔。建議服務器性能不是很好的網站,要慎重考慮。
- js和css文件在百度上搜一個壓縮網站就能壓縮,但是在實際開發的項目中,使用gulp、webpack等工具可以打包出合並壓縮后的文件,小圖片可以在打包時轉換成base64方式引入,大圖片可以被壓縮,html文件也是可以被壓縮的
- 使用 CDN 托管
- CDN的全稱是Content Delivery Network,即內容分發網絡。其基本思路是盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的狀況,提高用戶訪問網站的響應速度。
- 緩存的使用
- Ajax調用都采用緩存調用方式,一般采用附加特征參數方式實現,注意其中的<script src=”xxx.js?{VERHASH}”,{VERHASH}就是特征參數,這個參數不變化就使用緩存文件,如果發生變化則重新下載新文件或更新信息。
- css文件放置在head,js放置在文檔尾
- 在服務器端配置control-cache last-modify-date
-
在服務器配置Entity-Tag if-none-match
- 用更少的時間下載更多的文件,提高網站加載速度,提高用戶體驗,可以使用以下方法:
- 1.css sprites----將小圖片合並為一張大圖片,使用background-position等css屬性取得圖片位置
- 2.將資源放在多個域名下-----打開控制台,可以看到很多網站都是這么做的~
- 3.圖片延遲加載-----很多電商網站、新聞網站,尤其是用到瀑布流展示圖片的時候,很多都這么做了,這個技術已經很普遍~
- 書寫代碼的時候要注意優化:
- 1.css
- 將可以合並的樣式合並起來,比如margin-top、margin-bottom等。
- 給img圖片設置寬高,因為瀏覽器渲染元素的時候沒有找到這兩個參數,需要一邊下載圖片一邊計算大小,如果圖片很多,瀏覽器需要不斷地調整頁面。這不但影響速度,也影響瀏覽體驗。當瀏覽器知道了高度和寬度參數后,即使圖片暫時無法顯示,頁面上也會騰出圖片的空位,然后繼續加載后面的內容。從而加載時間快了,瀏覽體驗也更好了。
- 2.js
- 少改變DOM元素,少觸發reflow,可以復用的代碼提出來寫成公共的等等……
- 3.img
- 優化圖片,不失真的情況下盡量減少圖片大小,使用iconfont等
- 1.css
4. 怎么學習前端? 怎么接觸web新知識?
5. 關於前后端分離:
- 前端:負責View和Controller層。
- 后端:只負責Model層,業務處理/數據等。
6. 關於瀏覽器內核(渲染引擎)
- 先說一下瀏覽器的結構:
- ①、用戶界面(UI) - 包括菜單欄、工具欄、地址欄、后退/前進按鈕、書簽目錄等,也就是能看到的除了顯示頁面的主窗口之外的部分;
- ②、瀏覽器引擎(Rendering engine) - 也被稱為瀏覽器內核、渲染引擎,主要負責取得頁面內容、整理信息(應用CSS)、計算頁面的顯示方式,然后會輸出到顯示器或者打印機;
- ③、JS解釋器 - 也可以稱為JS內核,主要負責處理javascript腳本程序,一般都會附帶在瀏覽器之中,例如chrome的V8引擎;
- ④、網絡部分 - 主要用於網絡調用,例如:HTTP請求,其接口與平台無關,並為所有的平台提供底層實現;
- ⑤、UI后端 - 用於繪制基本的窗口部件,比如組合框和窗口等。
- ⑥、數據存儲 - 保存類似於cookie、storage等數據部分,HTML5新增了web database技術,一種完整的輕量級客戶端存儲技術。
- 注:IE只為每個瀏覽器窗口啟用單獨的進程,而chrome瀏覽器卻為每個tab頁面單獨啟用進程,也就是每個tab都有獨立的渲染引擎實例。
- 現在的主要瀏覽器:
- IE、Firefox、Safari、Chrome、Opera。
- 它們的瀏覽器內核(渲染引擎):
- IE--Trident、
- FF(Mozilla)--Gecko、
- Safari--Webkit、
- Chrome--Blink(WebKit的分支)、
- Opera--原為Presto,現為Blink。
- 因此在開發中,兼容IE、FF、Opera(Presto引擎是逐步放棄的)、Chrome和Safari中的一種即可,Safari、Chrome的引擎是相似的。
7. 瀏覽器加載文件(repaint/reflow)
- 文件加載順序
- 瀏覽器加載頁面上引用的CSS、JS文件、圖片時,是按順序從上到下加載的,每個瀏覽器可以同時下載文件的個數不同,因此經常有網站將靜態文件放在不同的域名下,這樣可以加快網站打開的速度。
- reflow
- 在加載JS文件時,瀏覽器會阻止頁面的渲染,因此將js放在頁面底部比較好。
- 因為如果JS文件中有修改DOM的地方,瀏覽器會倒回去把已經渲染過的元素重新渲染一遍,這個回退的過程叫reflow。
- CSS文件雖然不影響js文件的加載,但是卻影響js文件的執行,即使js文件內只有一行代碼,也會造成阻塞。因為可能會有var width = $('#id').width()這樣的語句,這意味着,js代碼執行前,瀏覽器必須保證css文件已下載和解析完成。
- 辦法:當js文件不需要依賴css文件時,可以將js文件放在頭部css的前面。
- 常見的能引起reflow的行為:
- 1.改變窗囗大小
- 2.改變文字大小
- 3.添加/刪除樣式表
- 4.腳本操作DOM
- 5.設置style屬性
- 等等……
- reflow是不可避免的,只能盡量減小,常用的方法有:
- 1.盡量不用行內樣式style屬性,操作元素樣式的時候用添加去掉class類的方式
- 2.給元素加動畫的時候,可以把該元素的定位設置成absolute或者fixed,這樣不會影響其他元素
- repaint
- 另外,有個和reflow相似的術語,叫做repaint(重繪),在元素改變樣式的時候觸發,這個比reflow造成的影響要小,所以能觸發repaint解決的時候就不要觸發reflow……
8. 為什么利用多個域名來請求網絡資源會更有效?
- 動靜分離需求,使用不同的服務器處理請求。處理動態內容的只處理動態內容,不處理別的,提高效率。CDN緩存更方便
- 突破瀏覽器並發限制:相關問題: 瀏覽器同一時間可以從一個域名下載多少資源?(即: 瀏覽器並發請求數)
- 也就是說:同一時間針對同一域名下的請求有一定數量限制。超過限制數目的請求會被阻止。不同瀏覽器這個限制的數目不一樣。
- Cookieless, 節省帶寬,尤其是上行帶寬 一般比下行要慢。
用戶的每次訪問,都會帶上自己的cookie ,挺大的。假如twitter 的圖片放在主站域名下,那么用戶每次訪問圖片時,request header 里就會帶有自己的cookie ,header 里的cookie 還不能壓縮,而圖片是不需要知道用戶的cookie 的,所以這部分帶寬就白白浪費了。
- 節約主域名的連接數,從而提高客戶端網絡帶寬的利用率,優化頁面響應。因為老的瀏覽器(IE6是典型),針對同一個域名只允許同時保持兩個HTTP連接。將圖片等資源請求分配到其他域名上,避免了大圖片之類的並不一定重要的內容阻塞住主域名上其他后續資源的連接(比如ajax請求)。
- 避免不必要的安全問題( 上傳js竊取主站cookie之類的)
9. 進程和線程的區別
- 一個程序至少有一個進程,一個進程至少有一個線程.
- 線程的划分尺度小於進程,使得多線程程序的並發性高。
- 線程是獨立調度的基本單位, 進程是擁有資源的基本單位
- 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
- 線程在執行過程中與進程還是有區別的。
- 每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。
- 但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
- 從邏輯角度來看,
- 多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。
10. 前端開發的優化問題
- 前端開發的優化問題:
- 如何控制網頁在網絡傳輸過程中的數據量
11. Flash、Ajax各自的優缺點,在使用中如何取舍?
- Ajax的優勢
(1) 可搜索型
(2) 開放性
(3) 費用
(4) 易用性
(5) 易於開發
- Flash的優勢
(1) 多媒體處理
(2) 兼容性
(3) 矢量圖形 比SVG,Canvas優勢大很多
(4) 客戶端資源調度,比如麥克風,攝像頭
參考:前端開發的優化問題
二、CSS
1. CSS3
CSS3新特性:
- 新增各種CSS選擇器 (: not(.input): 所有class不是“input”的節點)
- 圓角border-radiuis
- 多列布局:multi-column layout
- 陰影和反射: multi-column layout
- 文字特效:text-shadow
- 線性漸變: gradient
- 旋轉:transform
- 縮放,定位,傾斜,動畫,多背景:transform: \scale(0.85,0.90) \ translate(0px, -30px) \ skew(-9deg, 0deg) \ Animation
參考:CSS3中的一些屬性
2. css居中的方式
3. 請寫一個簡單的幻燈效果頁面
4. 什么是無樣式內容閃爍?如何避免?
答:
- what?
- 如果使用import方法對CSS進行導入,會導致某些頁面在Windows 下的Internet Explorer出現一些奇怪的現象:以無樣式顯示頁面內容的瞬間閃爍,這種現象稱之為文檔樣式短暫失效(Flash of Unstyled Content),簡稱為FOUC。
- why?
- 使用import導入樣式表
- 將樣式表放在頁面底部
- 有幾個樣式表,放在頁面不同位置
- 原因即:當樣式表晚於結構性html加載,當加載到此樣式表時,頁面將停止之前的渲染。此樣式表被下載和解析后,將重新渲染頁面,也就出現了短暫的花屏現象。
- how?
- 使用LINK標簽將樣式表放在文檔HEAD中。
5. display:none 和 visibility: hidden的區別
- display:none 隱藏對應的元素,在文檔布局中不再給它分配空間,它各邊的元素會合攏,就當他從來不存在。
- visibility:hidden 隱藏對應的元素,但是在文檔布局中仍保留原來的空間。
6. 解釋浮動和工作原理
答:
- 浮動可以理解為讓某個div元素脫離標准流,漂浮在標准流之上,和標准流不是一個層次。
- 假如某個div元素A是浮動的,如果A元素上一個元素也是浮動的,那么A元素會跟隨在上一個元素的后邊(如果一行放不下這兩個元素,那么A元素會被擠到下一行);如果A元素上一個元素是標准流中的元素,那么A的相對垂直位置不會改變,也就是說A的頂部總是和上一個元素的底部對齊。
- 清除浮動是為了清除使用浮動元素產生的影響。浮動的元素,高度會塌陷,而高度的塌陷使我們頁面后面的布局不能正常顯示。
-
- 關於清除浮動:清除浮動可以理解為打破橫向排列。 clear: none | left | right | both
- 對於CSS的清除浮動(clear),一定要牢記:這個規則只能影響使用清除的元素本身,不能影響其他元素。
參考自: 經驗分享:CSS浮動(float,clear)通俗講解
7. 清除浮動
答:
- 在浮動元素后面添加空標簽 clear:both
- 給父標簽使用overflow: hidden/auto;zoom:1
- 父級div定義, 使用偽類:after和zoom
1
2
|
.clearfloat:after{display:block;clear:both;content:
""
;visibility:hidden;height:0}
.clearfloat{zoom:1}
|
zoom:1的作用: 觸發IE下的hasLayout。zoom是IE瀏覽器專有屬性,可以設置或檢索對象的縮放比例。
當設置了zoom的值之后,所設置的元素就會擴大或縮小,高度寬度就會重新計算了,這里一旦改變zoom值時其實也會發生重新渲染,運用這個原理,也就解決了ie下子元素浮動時候父元素不隨着自動擴大的問題。
8. 解釋CSS Sprites, 以及你要如何使用?
答: CSS Sprites其實就是把網頁中一些背景圖片整合到一張圖片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的組合進行背景定位,background-position可以用數字能精確的定位出背景圖片的位置。
9. 你最喜歡的圖片替換方法是什么,你如何選擇使用?
答:
1) <h1><img src="image.gif" alt="Image Replacement"></h1>
2) 移開文字:
1
2
3
4
|
<
h1
><
span
>Image Replacement</
span
></
h1
>
h1{ background:url(hello_world.gif) no-repeat; width: 150px; height: 35px; }
span { display: none; }
|
注意問題:①結構性需要增加一個標簽包裹文本 ②需要把背景圖設置在外標簽上,並把文本外標簽隱藏.
缺點: 不利於閱覽器瀏覽網頁
3) text-indent屬性,並且給其設置一個較大的負值,x達到隱藏文本的效果
1
2
3
4
5
6
7
8
|
<
h1
class="technique-three">w3cplus</
h1
>
.technique-three {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
text-indent: -9999px;
}
|
4) 我們此處使用一個透明的gif圖片,通過在img標簽中的“alt”屬性來彌補display:none。這樣閱讀器之類的就能閱讀到所替換的文本是什么
<h1 class="technique-five"> <img src="images/blank.gif" alt="w3cplus" /< <span>w3cplus</span> </h1>.technique-five {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
}
.technique-five span {
display: none;
}
5) 使用零高度來隱藏文本,但為了顯示背景圖片,需要設置一個與替換圖片一樣的大小的padding值
1
2
3
4
5
6
7
8
9
10
|
<
h1
class="technique-six">w3cplus</
h1
>
.technique-six {
width: 329px;
padding: 79px 0 0 0;
height: 0px;
font-size: 0;
background: url(images/w3cplus-logo.png);
overflow: hidden;
}
|
6) 通過把span的大小都設置為“0”,來達到隱藏文本效果,這樣閱讀器就能完全閱讀到,而且又達到了圖片替換文本的效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
h1
class="technique-seven">
<
span
>w3cplus</
span
>
</
h1
>
.technique-seven {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
}
.technique-seven span {
display: block;
width: 0;
height: 0;
font-size: 0;
overflow: hidden;
}
|
7) 利用一個空白的span標簽來放置背景圖片,並對其進行絕對定位,使用覆蓋文本,達到隱藏替換文本的效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
h1
class="technique-eight">
<
span
></
span
>w3cplus
</
h1
>
.technique-eight {
width: 329px;
height: 79px;
position: relative;
}
.technique-eight span {
background: url(images/w3cplus-logo.png);
position: absolute;
width: 100%;
height: 100%;
}
|
8) 設置字體為微小值,但這里需要注意一點不能忘了設置字體色和替換圖片色一樣,不然會有一個小點顯示出來
1
2
3
4
5
6
7
8
9
|
<
h1
class="technique-nine">w3cplus</
h1
>
.technique-nine {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
font-size: 1px;
color: white;
}
|
9) 使用css的clip屬性來實現圖片替換文本的效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<
h1
class="technique-ten"><
span
>w3cplus</
span
></
h1
>
.technique-ten {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
}
.technique-ten span {
border: 0 !important;
clip: rect(1px 1px 1px 1px);
clip: rect(1px,1px,1px,1px);
height: 1px !important;
margin: -1px;
overflow: hidden;
padding: 0 !important;
position: absolute !important;
width: 1px;
}
|
參考自: 十種圖片替換文本CSS方法
10. 討論CSS hacks, 條件引用或者其他
- hacks
- _width針對於ie6。*width,+width針對於ie6,7。
- color: red\9;/*IE8以及以下版本瀏覽器*/(但是測試可以兼容到ie10。
- *+html與*html是IE特有的標簽, firefox暫不支持.而*+html又為IE7特有標簽(但是測試*html兼容ie6-10。*+兼容ie7-10)。
- !important 在IE中會被忽視,ie6,7,8不識別,ie9+(包括ie9)是識別的。
- 條件引用
-
12345678910
<!--[if !IE]><!-->
除IE外都可識別
<!--<![endif]-->
<!--[if IE]> 所有的IE可識別 <![endif]-->
<!--[if IE 6]> 僅IE6可識別 <![endif]-->
<!--[if lt IE 6]> IE6以及IE6以下版本可識別 <![endif]-->
<!--[if gte IE 6]> IE6以及IE6以上版本可識別 <![endif]-->
<!--[if IE 7]> 僅IE7可識別 <![endif]-->
<!--[if lt IE 7]> IE7以及IE7以下版本可識別 <![endif]-->
<!--[if gte IE 7]> IE7以及IE7以上版本可識別 <![endif]-->
<!--[if IE 8]> 僅IE8可識別 <![endif]-->
<!--[if IE 9]> 僅IE9可識別 <![endif]-->
-
11. 如何為有功能限制的瀏覽器提供網頁?
答: 功能限制的瀏覽器, 比如低版本IE, 手機瀏覽器, 等會在很多功能上不符合Web標准, 而應對方式主要有:
- 只提供符合Web標准的頁面
- 提供另一個符合那些瀏覽器標准的頁面
- 兼容: 兩種思路:
- 漸進增強: 提供一個可用的原型,后來再為高級瀏覽器提供優化
- 優雅降級: 據高級瀏覽器提供一個版本,然后有功能限制的瀏覽器只需要一個剛好能用的版本
- 相關技術:
- Media Query
- CSS hack
- 條件判斷<! --[if !IE]><!-->除IE外都可識別<!--<![endif]-->
參考自: 如何為有功能限制的瀏覽器提供網頁
12. 在書寫高效 CSS 時會有哪些問題需要考慮?
答:
1)reset。參照下題“描述下 “reset” CSS 文件的作用和使用它的好處”的答案。
2)規范命名。尤其對於沒有語義化的html標簽,例如div,所賦予的class值要特別注意。
2)抽取可重用的部件,注意層疊樣式表的“優先級”。
13. 如何優化網頁的打印樣式?
針對打印機的樣式: @media print{...}
參考:如何優化網頁的打印樣式? 移動端H5知識普及 - CSS3媒體查詢
14. 描述下你曾經使用過的 CSS 預處理的優缺點
答: 優點:
- 結構清晰, 便於擴展
- 可以方便屏幕瀏覽器私有語法差異
- 可以輕松實現多重繼承
- 完全兼容css代碼
參考: 再談 CSS 預處理器
15. 如果設計中使用了非標准的字體,你該如何去實現?
- 圖片替代
- web : fonts在線字庫
- @font-face
16. 解釋下瀏覽器是如何判斷元素是否匹配某個 CSS 選擇器?
作者:張靖超鏈接:https://www.zhihu.com/question/24959507/answer/29672263來源:知乎著作權歸作者所有,轉載請聯系作者獲得授權。
瀏覽器先產生一個元素集合,這個集合往往由最后一個部分的索引產生(如果沒有索引就是所有元素的集合)。然后向上匹配,如果不符合上一個部分,就把元素從集合中刪除,直到真個選擇器都匹配完,還在集合中的元素就匹配這個選擇器了。
舉個例子,有選擇器:
body.ready #wrapper > .lol233
至此這個選擇器匹配結束,所有還在集合中的元素滿足。
大體就是這樣,不過瀏覽器還會有一些奇怪的優化。
為什么從后往前匹配因為效率和文檔流的解析方向。效率不必說,找元素的父親和之前的兄弟比遍歷所喲兒子快而且方便。關於文檔流的解析方向,是因為現在的 CSS,一個元素只要確定了這個元素在文檔流之前出現過的所有元素,就能確定他的匹配情況。應用在即使 html 沒有載入完成,瀏覽器也能根據已經載入的這一部分信息完全確定出現過的元素的屬性。
為什么是用集合主要也還是效率。基於 CSS Rule 數量遠遠小於元素數量的假設和索引的運用,遍歷每一條 CSS Rule 通過集合篩選,比遍歷每一個元素再遍歷每一條 Rule 匹配要快得多。
17. 解釋一下你對盒模型的理解,以及如何在 CSS 中告訴瀏覽器使用不同的盒模型來渲染你的布局。
答:
盒模型:文檔中的每個元素被描繪為矩形盒子,渲染引擎的目的就是判定大小,屬性——比如它的顏色、背景、邊框方面——及這些盒子的位置。
在CSS中,這些矩形盒子用標准盒模型來描述。這個模型描述了一個元素所占用的空間。每一個盒子有四條邊界:外邊距邊界margin edge,邊框邊界border edge,內邊距邊界padding edge和內容邊界content edge。
內容區域是真正包含元素內容的區域,位於內容邊界的內部,它的大小為內容寬度或content-box寬及內容高度或content-box高。如果box-sizing為默認值,width、min-width、max-width、height、min-height和max-height控制內容大小。
內邊距區域padding area用內容可能的邊框之間的空白區域擴展內容區域。通常有背景——顏色或圖片(不透明圖片蓋住背景顏色)。
邊框區域擴展了內邊距區域。它位於邊框邊界內部,大小為border-box寬和border-box高。
外邊距區域margin area用空白區域擴展邊框區域,以分開相鄰的元素。它的大小為margin-box的高寬。
在外邊距合並的情況下,由於盒之間共享外邊距,外邊距不容易弄清楚。
對於非替換的行內元素來說,盡管內容周圍存在內邊距與邊框,但其占用空間(行高)由line-height屬性決定。
盒子模型分為兩類:W3C標准盒子模型和IE盒子模型 (微軟確實不喜歡服從他家的標准)
這兩者的關鍵差別就在於:
-
- W3C盒子模型——屬性高(height)和屬性寬(width)這兩個值不包含 填充(padding)和邊框(border )
- IE盒子模型——屬性高(height)和屬性寬(width)這兩個值包含 填充(padding)和邊框(border)
我們在編寫頁面代碼的時候應該盡量使用標准的W3C盒子模型(需要在頁面中聲明DOCTYPE類型)。
各瀏覽器盒模型的組成結構是一致的,區別只是在"怪異模式"下寬度和高度的計算方式,而“標准模式”下則沒有區別。組成結構以寬度為例:總寬度=marginLeft+borderLeft+paddingLeft+contentWidth+paddingRight+borderRight+marginRight(W3C標准盒子模型)。頁面在“怪異模式”下,css中為元素的width和height設置的值在標准瀏覽器和ie系列(ie9除外)里的代表的含義是不同的(IE盒子模型)。
因而解決兼容型為題最簡潔和值得推薦的方式是:下述的第一條。
- 將頁面設為“標准模式”。添加對應的dtd標識
- 使用hack或者在外面套上一層wrapper
參考: 解釋一下你對盒模型的理解,以及如何在 CSS 中告訴瀏覽器使用不同的盒模型來渲染你的布局。
18. 偽類的用法:
19. 描述下"reset"css文件的作用和使用它的好處
reset.css能夠重置瀏覽器的默認屬性。不同的瀏覽器具有不同的樣式,重置能夠使其統一。比如說ie瀏覽器和FF瀏覽器下button顯示不同,通過reset能夠統一樣式,顯示相同的效果。但是很多reset是沒必要的,多寫了會增加瀏覽器在渲染頁面的負擔。
比如說,
1)我們不應該對行內元素設置無效的屬性,對span設置width和height,margin都不會生效的。
2)對於absolute和fixed定位的固定尺寸(設置了width和height屬性),如果設置了top和left屬性,那么bottom和right,margin和float就沒有作用。
3)后面設置的屬性將會覆蓋前面重復設置的屬性。
- 期待能夠指出它的負面影響,或者提到它的一個更好的替換者"normalize" normalize.css是一個可以定制的css文件,它讓不同的瀏覽器在渲染元素時形式更統一。
20. 請解釋一下 * { box-sizing: border-box; } 的作用, 並且說明使用它有什么好處?
說到 IE 的 bug,在 IE6以前的版本中,IE對盒模型的解析出現一些問題,跟其它瀏覽器不同,將 border 與 padding 都包含在 width 之內。而另外一些瀏覽器則與它相反,是不包括border和padding的。對於IE瀏覽器,當我們設置 box-sizing: content-box; 時,瀏覽器對盒模型的解釋遵從我們之前認識到的 W3C 標准,當它定義width和height時,它的寬度不包括border和padding;對於非IE瀏覽器,當我們設置box-sizing: border-box; 時,瀏覽器對盒模型的解釋與 IE6之前的版本相同,當它定義width和height時,border和padding則是被包含在寬高之內的。內容的寬和高可以通過定義的“width”和 “height”減去相應方向的“padding”和“border”的寬度得到。內容的寬和高必須保證不能為負,必要時將自動增大該元素border box的尺寸以使其內容的寬或高最小為0。
使用 * { box-sizing: border-box; }能夠統一IE和非IE瀏覽器之間的差異。
21. block, inline和inline-block的區別
答:
- 起新行
- block元素會獨占一行, 多個block元素會各自新起一行. 默認情況下, block元素寬度自動填滿其父元素寬度
- inline元素不會獨占一行, 多個相鄰的行內元素會排列在同一行里, 直到一行排列不下, 才會新換一行, 其寬度隨元素的內容而變化
- 設置寬高
- block元素可以設置width, height屬性. 塊級元素即使設置了寬度, 仍然獨占一行
- inline元素設置width, height無效
- 內外邊距
- block元素可以設置margin和padding屬性
- inline元素的margin和padding屬性,水平方向的padding-left, padding-right, margin-left, margin-right都會產生邊距效果. 但是數值方向的 margin/padding-top/bottom不會產生邊距效果
- 包含
- block可以包含inline和block元素,而inline元只能包含inline元素
- 而display: inline-block, 則是將對象呈現為inline對象, 但是對象的內容作為block對象呈現. 之后的內聯對象會被排列到一行內. 比如我們可以給一個link(a元素)inline-block的屬性, 使其既有block的高寬特性又有inline的同行特性
22. css動畫和js動畫的優缺點
CSS3的動畫
- 優點:
- 1.在性能上會稍微好一些,瀏覽器會對CSS3的動畫做一些優化(比如專門新建一個圖層用來跑動畫)
- 2.代碼相對簡單
- 缺點:
- 1.在動畫控制上不夠靈活
- 2.兼容性不好
- 3.部分動畫功能無法實現(如滾動動畫,視差滾動等)
JavaScript的動畫
- 優點:
- 1.控制能力很強,可以單幀的控制、變換
- 2.兼容性好,寫得好完全可以兼容IE6,且功能強大。
- 缺點:
- 計算沒有css快,另外經常需要依賴其他的庫。
結論
- 所以,不復雜的動畫完全可以用css實現,復雜一些的,或者需要交互的時候,用js會靠譜一些~
23. 你用過媒體查詢,或針對移動端的布局/CSS 嗎?
答:
通過媒體查詢可以為不同大小和尺寸的媒體定義不同的css,適合相應的設備顯示;即響應式布局
- @media screen and (min-width: 400px) and (max-width: 700px) { … }
- @media handheld and (min-width: 20em), screen and (min-width: 20em) { … }
參考自: CSS3媒體查詢 使用 CSS 媒體查詢創建響應式網站 《響應式Web設計實踐》學習筆記
24. 有哪些隱藏內容的方法(同時還要保證屏幕閱讀器可用)
答:
display:none或者visibility:hidden,overflow:hidden。
- 1.display:none;的缺陷
- 搜索引擎可能認為被隱藏的文字屬於垃圾信息而被忽略
- 屏幕閱讀器(是為視覺上有障礙的人設計的讀取屏幕內容的程序)會忽略被隱藏的文字。
- 2.visibility: hidden ;的缺陷
- 隱藏的內容會占據他所應該占據物理空間
- 3.overflow:hidden;一個比較合理的方法
- 例:.texthidden { display:block; overflow: hidden; width: 0; height: 0; }
- 將寬度和高度設定為0,然后超過部分隱藏,就會彌補上述一、二方法中的缺陷,也達到了隱藏內容的目的
- 例:.texthidden { display:block; overflow: hidden; width: 0; height: 0; }
25. CSS選擇器級別
- 1.如果樣式是行內樣式(通過Style=””定義),那么a=1
- 2.b為ID選擇器的總數
- 3.c為Class類選擇器的數量。
- 4.d為類型選擇器的數量
- 5.屬性選擇器,偽類選擇器和class類選擇器優先級一樣,偽元素選擇器和類型選擇器一樣
- 6.!important 權重最高,比 inline style 還要高。
一般來講,越詳細的級別越高。CSS優先級包含四個級別(文內選擇符,ID選擇符,Class選擇符,元素選擇符)以及各級別出現的次數。根據這四個級別出現的次數計算得到CSS的優先級
參考: CSS樣式選擇器優先級
26. img設置屬性title和alt的區別?
答:
- Alt是img的特有屬性, 或與<input type="image">配合使用,規定圖像的替代文本. 如果無法顯示圖像, 瀏覽器將顯示替代文本. 用於圖片無法加載顯示、讀屏器閱讀圖片,可提高圖片可 訪問性,搜索引擎會重點分析。最長可包含1024個字符,
- Title為元素提供附加的提示信息,用於鼠標滑到元素上的時候顯示。其值可以比alt屬性值設置的更長, 但是有些瀏覽器會截斷過長的文字.
27. 知道BFC嗎?
答: BFC指的是Block Formatting Context, 它提供了一個環境, html元素在這個環境中按照一定規則進行布局. 一個環境中的元素不會影響到其他環境中的布局. 決定了元素如何對其內容進行定位, 以及和其他元素的關系和相互作用.
其中: FC(Formatting Context): 指的是頁面中的一個渲染區域, 並且擁有一套渲染規則, 它決定了其子元素如何定位, 以及與其他元素的相互關系和作用.
BFC: 塊級格式化上下文, 指的是一個獨立的塊級渲染區域, 只有block-level box參與, 該區域擁有一套渲染規則來約束塊級盒子的布局, 且與區域外部無關.
- BFC的生成:
- 根元素
- float的值不為none
- overflow的值不為visible
- display的值為 inline-block, table-cell, table-caption
- position的值為absolute或fixed
- BFC的約束規則
- 生成BFC元素的子元素會一個接一個的放置。垂直方向上他們的起點是一個包含塊的頂部,兩個相鄰子元素之間的垂直距離取決於元素的margin特性。在BFC中相鄰的塊級元素外邊距會折疊。
- 生成BFC元素的子元素中,每一個子元素做外邊距與包含塊的左邊界相接觸,(對於從右到左的格式化,右外邊距接觸右邊界),即使浮動元素也是如此(盡管子元素的內容區域會由於浮動而壓縮),除非這個子元素也創建了一個新的BFC(如它自身也是一個浮動元素)。
- 分解:
-
- 內部的Box會在垂直方向上一個接一個的放置
- 垂直方向上的距離由margin決定。(完整的說法是:屬於同一個BFC的兩個相鄰Box的margin會發生重疊,與方向無關。)
- 每個元素的左外邊距與包含塊的左邊界相接觸(從左向右),即使浮動元素也是如此。(這說明BFC中子元素不會超出他的包含塊,而position為absolute的元素可以超出他的包含塊邊界)
- BFC的區域不會與float的元素區域重疊
- 計算BFC的高度時,浮動子元素也參與計算
- BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面元素,反之亦然
- BFC在布局中的應用
- 不和浮動元素重疊:
- 如果一個浮動元素后面跟着一個非浮動元素, 就會產生覆蓋
- 防止margin重疊:
- 同一個BFC中的兩個相鄰Box才會發生重疊與方向無關,不過由於上文提到的第一條限制,我們甚少看到水平方向的margin重疊。這在IE中是個例外,IE可以設置write-mode
- 解決浮動相關問題
- 父元素: overflow:hidden IE: zoom:1(hasLayout)
- 根本原因在於創建BFC的元素,子浮動元素也會參與其高度計算,即不會產生高度塌陷問題。實際上只要讓父元素生成BFC即可,並不只有這兩種方式。
- 多欄布局
- 比如左右兩欄寬度固定, 中間欄自適應 則中間欄設置 overflow:hidden生成BFC
- 不和浮動元素重疊:
- IE中類似概念: hasLayout
參考: 我對BFC的理解 CSS BFC和IE Haslayout介紹
28. 行內元素有哪些?塊級元素有哪些?空元素有哪些?
答:
- 行內元素有:span img input select strong
- 塊級元素有:div ul ol dl dt dd h1 h2 h3 h4 p...
- 常見的空元素:br hr img input link meta base area command embed keygen param source track wbr....
三、html
1. h5的改進:
- 新元素
- 畫布canvas: HTML5 <canvas> 元素用於圖形的繪制,通過腳本 (通常是JavaScript)來完成
- 音頻audio
- 視頻video
- 語義性: article, nav , footer, section, aside, hgroup等.
- 時間time
- 新屬性
- 拖放: draggable <img draggable="true">
- 可編輯: contenteditable
- 新事件
- 拖放 ondrag ondrop
- 關閉頁面 onunload
- 窗口大小改變 onresize
- 取消了一些元素: font center等
- 新的DOCTYPE聲明 <!DOCTYPE html>
- 完全支持CSS3
- Video和Audio
- 2D/3D制圖
- 本地存儲
- 本地SQL數據
- Web應用
參考自: 猿教程
2. 什么是語義化的html?
答:
- what?
- 根據內容的結構(內容語義化),選擇合適的標簽(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。
- why?
- 為了在沒有CSS的情況下,頁面也能呈現出很好地內容結構、代碼結構:為了裸奔時好看;
- 用戶體驗:例如title、alt用於解釋名詞或解釋圖片信息、label標簽的活用;
- 有利於SEO:和搜索引擎建立良好溝通,有助於爬蟲抓取更多的有效信息:爬蟲依賴於標簽來確定上下文和各個關鍵字的權重
- 方便其他設備解析(如屏幕閱讀器、盲人閱讀器、移動設備)以意義的方式來渲染網頁;
- 便於團隊開發和維護,語義化更具可讀性,是下一步吧網頁的重要動向,遵循W3C標准的團隊都遵循這個標准,可以減少差異化。
- how?
- 盡可能少的使用無語義的標簽div和span;
- 在語義不明顯時,既可以使用div或者p時,盡量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;
- 不要使用純樣式標簽,如:b、font、u等,改用css設置。
- 需要強調的文本,可以包含在strong或者em標簽中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);
- 使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;
- 表單域要用fieldset標簽包起來,並用legend標簽說明表單的用途;
- 每個input標簽對應的說明文本都需要使用label標簽,並且通過為input設置id屬性,在lable標簽中設置for=someld來讓說明文本和相對應的input關聯起來。
參考自: 理解HTML語義化
3. 從前端角度出發談談做好seo需要考慮什么?
答:
- 語義化html標簽
- 合理的title, description, keywords;
- 重要的html代碼放前面
- 少用iframe, 搜索引擎不會抓取iframe中的內容
- 圖片加上alt
4. 文檔類型(DOCTYPE)
答:
- 作用: doctype聲明位於文檔中最前面的位置,處於標簽之前,告知瀏覽器使用的是哪種規范。
- 類型: 三種: Strict、Transitional 以及 Frameset
- 如果不聲明: 不寫doctype,瀏覽器會進入quirks mode (混雜模式)。即,如果不聲明doctype,瀏覽器不引入w3c的標准,那么早期的瀏覽器會按照自己的解析方式渲染頁面。瀏覽器采用自身方式解析頁面的行為稱為"quirks mode(混雜模式也稱怪異模式)";采用w3c方式解析就是"strict mode(標准模式)"。 如果完全采用strictmode就不會出任何的差錯,但這樣會降低程序的容錯率,加重開發人員的難度
- 用哪種:
- 沒有doctype聲明的采用quirks mode解析
- 對於有doctype的大多數采用standard mord。
- 特殊情況:
- 對於那些瀏覽器不能識別的doctype ,瀏覽器采用quirks mode;
- 沒有聲明DTD或者html版本聲明低於4.0采用quirks mode,其他使用standard mode;
- ie6中,如果在doctype聲明前有一個xml聲明(比如:<?xml version="1.0" encoding="iso-8859-1"?>),則采用quirks mode解析
- 標准模式與怪異模式的區別:
- 標准模式:瀏覽器根據規范呈現頁面
- 混雜模式(怪異模式):頁面以一種比較寬松的兼容方式顯示。
- 他們最大的不同是對盒模型的解析。
- 在strict mode中 :width是內容寬度 ,也就是說,元素真正的寬度 = margin-left + border-left-width + padding-left + width + padding-right + border-right- width + margin-right;
- 在quirks mode中 :width則是元素的實際寬度 ,內容寬度 = width - (margin-left + margin-right + padding-left + padding-right + border-left-width + border-right-width)
5. 使用XHTML的局限有哪些?
答:
- XHTML較為嚴格,標簽必須閉合,必須要body,head等
- 如果頁面使用 'application/xhtml+xml' 一些老的瀏覽器並不兼容
6. 如果網頁內容需要多語言,要怎么做?
答: 采用統一編碼utf-8模式
1
2
3
4
5
6
7
8
9
10
11
|
<META HTTP-EQUIV=“Content-Type” CONTENT=“text/html; CHARSET=字符集">
不寫,根據瀏覽器默認字符集顯示
charset=gb2312 簡體中文
charset=big5 繁體中文
charset=EUC_KR 韓語
charset=Shift_JIS 或 EUC_JP 日語
charset= KOI8-R / Windows-1251 俄語
charset=iso-8859-1 西歐語系(荷蘭語,英語,法語,德語,意大利語,挪威語,葡萄牙語,瑞士語.等十八種語言)
charset=iso-8859-2 中歐語系
charset=iso-8859-5 斯拉夫語系(保加利亞語,Byelorussian語,馬其頓語,俄語,塞爾維亞語,烏克蘭語等)
charset=uft-8 unicode多語言
|
參考自: 多語言的網站怎么做呀 多語言網站設計需要注意的問題
7. data-*屬性的作用
- html5規范里增加了一個自定義data屬性
-
為前端開發者提供自定義的屬性,這些屬性集可以通過對象的dataset屬性獲取,不支持該屬性的瀏覽器可以通過 getAttribute方法獲取
<div data-author="david" data-time="2011-06-20" data-comment-num="10">...</div>
div.dataset.commentNum; // 可通過js獲取 10 - data-為前端開發者提供自定義的屬性,這些屬性集可以通過對象的dataset屬性獲取,不支持該屬性的瀏覽器可以通過 getAttribute方法獲取。ppk提到過使用rel屬性,lightbox庫推廣了rel屬性,HTML5提供了data-做替代,這樣可以更好 地使用自定義的屬性
- 需要注意的是,data-之后的以連字符分割的多個單詞組成的屬性,獲取的時候使用駝峰風格。
8. 如果把 HTML5 看作做一個開放平台,那它的構建模塊有哪些?
答:
1)Web Storage API
2)基於位置服務LBS
3)無插件播放音頻視頻
4)調用相機和GPU圖像處理單元等硬件設備
5)拖拽和Form API
9. 請描述一下 cookies,sessionStorage 和 localStorage 的區別?
答:
- cookie:
- cookie是網站為了標示用戶身份而儲存在用戶本地終端(Client Side)上的數據(通常經過加密)。
- cookie數據始終在同源的http請求中攜帶(即使不需要),記會在瀏覽器和服務器間來回傳遞。
- sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。
- 存儲大小:
- cookie數據大小不能超過4k。
- sessionStorage和localStorage 雖然也有存儲大小的限制,但比cookie大得多,可以達到5M或更大。
- 有期時間:
- localStorage 存儲持久數據,瀏覽器關閉后數據不丟失除非主動刪除數據;
- sessionStorage 數據在當前瀏覽器窗口關閉后自動刪除。
- cookie 設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉
- 作用域不同:
- sessionStorage不在不同的瀏覽器窗口中共享,即使是同一個頁面;
- localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
- Web Storage 支持事件通知機制,可以將數據更新的通知發送給監聽者。
- Web Storage 的 api 接口使用更方便。

sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,這兩種方式都允許開發者使用js設置的鍵值對進行操作,在在重新加載不同的頁面的時候讀出它們。這一點與cookie類似。可以方便的在web請求之間保存數據。有了本地數據,就可以避免數據在瀏覽器和服務器間不必要地來回傳遞。 sessionStorage、localStorage、cookie都是在瀏覽器端存儲的數據, 其中sessionStorage的概念很特別,引入了一個“瀏覽器窗口”的概念。 sessionStorage是在同源的同窗口(或tab)中,始終存在的數據。也就是說只要這個瀏覽器窗口沒有關閉,即使刷新頁面或進入同源另一頁面,數據仍然存在。關閉窗口后,sessionStorage即被銷毀。同時“獨立”打開的不同窗口,即使是同一頁面,sessionStorage對象也是不同的。 Web Storage 數據完全存儲在客戶端, 不需要通過瀏覽器的請求將數據傳給服務器, 因此比cookies能夠存儲更多的數據,大概5M左右 Web Storage帶來的好處:使用 local storage和session storage主要通過在js中操作這兩個對象來實現,分別為window.localStorage和window.sessionStorage. 這兩個對象均是Storage類的兩個實例,自然也具有Storage類的屬性和方法。 減少網絡流量:一旦數據保存在本地后,就可以避免再向服務器請求數據,因此減少不必要的數據請求,減少數據在瀏覽器和服務器間不必要地來回傳遞。 快速顯示數據:性能好,從本地讀數據比通過網絡從服務器獲得數據快得多,本地數據可以即時獲得。再加上網頁本身也可以有緩存,因此整個頁面和數據都在本地的話,可以立即顯示。 臨時存儲:很多時候數據只需要在用戶瀏覽一組頁面期間使用,關閉窗口后數據就可以丟棄了,這種情況使用sessionStorage非常方便。
10. 瀏覽器本地存儲與服務器端存儲之間的區別
- 其實數據既可以在瀏覽器本地存儲,也可以在服務器端存儲。
- 瀏覽器端可以保存一些數據,需要的時候直接從本地獲取,sessionStorage、localStorage和cookie都由瀏覽器存儲在本地的數據。
- 服務器端也可以保存所有用戶的所有數據,但需要的時候瀏覽器要向服務器請求數據。
- 1.服務器端可以保存用戶的持久數據,如數據庫和雲存儲將用戶的大量數據保存在服務器端。
- 2.服務器端也可以保存用戶的臨時會話數據。服務器端的session機制,如jsp的 session 對象,數據保存在服務器上。實現上,服務器和瀏覽器之間僅需傳遞session id即可,服務器根據session id找到對應用戶的session對象。會話數據僅在一段時間內有效,這個時間就是server端設置的session有效期。
- 服務器端保存所有的用戶的數據,所以服務器端的開銷較大,而瀏覽器端保存則把不同用戶需要的數據分布保存在用戶各自的瀏覽器中。
- 瀏覽器端一般只用來存儲小數據,而服務器可以存儲大數據或小數據。
- 服務器存儲數據安全一些,瀏覽器只適合存儲一般數據。
11. sessionStorage和頁面js數據對象的區別
答:
- 頁面中一般的 js 對象或數據的生存期是僅在當前頁面有效,因此刷新頁面或轉到另一頁面這樣的重新加載頁面的情況,數據就不存在了。
- 而sessionStorage 只要同源的同窗口(或tab)中,刷新頁面或進入同源的不同頁面,數據始終存在。也就是說只要這個瀏覽器窗口沒有關閉,加載新頁面或重新加載,數據仍然存在。
12. canvas和svg的區別?
答:
- svg:
- SVG是一種使用XML描述2D圖形的語言
- SVG基於XML, 這意味着SVG DOM中的每個元素都是可用的. 所以可以為每個元素附加JavaScript事件處理器
- 在SVG中, 每個被繪制的圖像均被視為對象. 如果SVG對象的屬性發生變化, 那么瀏覽器能夠自動重現圖像
- Canvas
- Canvas通過js來繪制2D圖形
- Canvas是逐像素進行渲染的
- 在Canvas中, 一旦圖形被繪制完成, 它就不會繼續得到瀏覽器的關注. 如果其位置發生變化, 那么整個場景也需要重新繪制, 包括任何或許已被圖形覆蓋的對象.
- 區別
- Canvas支持分辨率, SVG不支持
- Canvas不支持事件處理器, SVG支持
- Canvas只有弱的文本渲染能力, 而SVG最適合帶有大型渲染區域的應用程序(比如谷歌地圖)
- Canvas能夠以.png或.jpg格式保存結果圖像
- SVG的復雜度過高的話會減慢渲染速度(任何過度使用DOM的應用都不快)
- Canvas最適合圖像密集型的游戲, 其中的許多對象會被頻繁重繪. 而SVG不適合游戲應用
- Canvas是基於位圖的圖像,它不能夠改變大小, 只能縮放顯示; SVG是基於矢量的, 所以它能夠很好地處理圖形大小的改變
- Canvas提供的功能更原始, 適合像素處理, 動態渲染和大數據量繪制; SVG功能更完善, 適合靜態圖片顯示, 高保真文檔查看和打印的應用場景
- 繪制Canvas對象后, 不能使用腳本和CSS對它進行修改; 而SVG對象是文檔對象模型的一部分, 所以可以隨時使用腳本和CSS修改它們
13. src和href的區別?
答:
- src指向外部資源的位置, 用於替換當前元素, 比如js腳本, 圖片等元素
- href指向網絡資源所在的位置, 用於在當前文檔和引用資源間確定聯系, 加載css
四、js
1. ajax, 跨域, jsonp
參考: 《JavaScript》高級程序設計第21章:Ajax和Comet
2. apply和call的用法和區別:
- 用法: 都能繼承另一個對象的方法和屬性,區別在於參數列表不一樣
- 區別:
- Function.apply(obj, args) args是一個數組,作為參數傳給Function
- Function.call(obj, arg1, arg2,...) arg*是參數列表
- apply一個妙用: 可以將一個數組默認的轉化為一個參數列表
- 舉個栗子: 有一個數組arr要push進一個新的數組中去, 如果用call的話需要把數組中的元素一個個取出來再push, 而用apply只有Array.prototype.push.apply(this, arr)
參考自: 區別和詳解:js中call()和apply()的用法
3. bind函數的兼容性
- 用法:
- bind()函數會創建一個新函數, 為綁定函數。當調用這個綁定函數時,綁定函數會以創建它時傳入bind方法的第一個參數作為this,傳入bind方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數.
- 一個綁定函數也能使用
new
操作符創建對象:這種行為就像把原函數當成構造器。提供的 this 值被忽略,同時調用時的參數被提供給模擬函數。
4. 解釋下事件代理
答: 事件委托利用了事件冒泡, 只指定一個事件處理程序, 就可以管理某一類型的所有事件.
例:
html部分: 要點擊li彈出其id
<ul id="list"> <li id="li-1">Li 2</li> <li id="li-2">Li 3</li> <li id="li-3">Li 4</li> <li id="li-4">Li 5</li> <li id="li-5">Li 6</li> <li id="li-6">Li 7</li> </ul>
//js部分
document.getElementById("list").addHandler("click", function(e){ var e = e || window.event; var target = e.target || e.srcElement; if(target.nodeName.toUpperCase == "LI"){ console.log("List item", e,target.id, "was clicked!"); } });
5. 解釋下js中this是怎么工作的?
答:
this 在 JavaScript 中主要由以下五種使用場景。
- 作為函數調用,this 綁定全局對象,瀏覽器環境全局對象為 window 。
- 內部函數內部函數的 this 也綁定全局對象,應該綁定到其外層函數對應的對象上,這是 JavaScript的缺陷,用that替換。
- 作為構造函數使用,this 綁定到新創建的對象。
- 作為對象方法使用,this 綁定到該對象。
- 使用apply或call調用 this 將會被顯式設置為函數調用的第一個參數。
6. 繼承
參考:js怎么實現繼承?
7. AMD vs. CommonJS?
答: AMD是依賴提前加載,CMD是依賴延時加載
8. 什么是哈希表?
答: 哈希表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。
使用哈希查找有兩個步驟:
- 使用哈希函數將被查找的鍵轉換為數組的索引。在理想的情況下,不同的鍵會被轉換為不同的索引值,但是在有些情況下我們需要處理多個鍵被哈希到同一個索引值的情況。所以哈希查找的第二個步驟就是處理沖突
- 處理哈希碰撞沖突。有很多處理哈希碰撞沖突的方法,比如拉鏈法和線性探測法。
元素特征轉變為數組下標的方法就是散列法。散列法當然不止一種,下面列出三種比較常用的:
1,除法散列法
最直觀的一種,上圖使用的就是這種散列法,公式:
index = value % 16
學過匯編的都知道,求模數其實是通過一個除法運算得到的,所以叫“除法散列法”。
2,平方散列法
求index是非常頻繁的操作,而乘法的運算要比除法來得省時(對現在的CPU來說,估計我們感覺不出來),所以我們考慮把除法換成乘法和一個位移操作。公式:
index = (value * value) >> 28 (右移,除以2^28。記法:左移變大,是乘。右移變小,是除。)
如果數值分配比較均勻的話這種方法能得到不錯的結果,但我上面畫的那個圖的各個元素的值算出來的index都是0——非常失敗。也許你還有個問題,value如果很大,value * value不會溢出嗎?答案是會的,但我們這個乘法不關心溢出,因為我們根本不是為了獲取相乘結果,而是為了獲取index。
3,斐波那契(Fibonacci)散列法
解決沖突的方法:
1. 拉鏈法
將大小為M 的數組的每一個元素指向一個條鏈表,鏈表中的每一個節點都存儲散列值為該索引的鍵值對,這就是拉鏈法.
對采用拉鏈法的哈希實現的查找分為兩步,首先是根據散列值找到等一應的鏈表,然后沿着鏈表順序找到相應的鍵。
2. 線性探測法:
使用數組中的空位解決碰撞沖突
參考: 哈希表的工作原理 淺談算法和數據結構: 十一 哈希表
9. 什么是閉包? 閉包有什么作用?
答:
- 閉包是指有權訪問另一個函數作用域中的變量的函數. 創建閉包常見方式,就是在一個函數內部創建另一個函數.
- 作用:
- 匿名自執行函數 (function (){ ... })(); 創建了一個匿名的函數,並立即執行它,由於外部無法引用它內部的變量,因此在執行完后很快就會被釋放,關鍵是這種機制不會污染全局對象。
- 緩存, 可保留函數內部的值
- 實現封裝
- 實現模板
參考自: js閉包的用途
10. 偽數組:
- 什么是偽數組:
- 偽數組是能通過Array.prototype.slice 轉換為真正的數組的帶有length屬性的對象
- 比如arguments對象,還有像調用getElementsByTagName,document.childNodes之類的,它們都返回NodeList對象都屬於偽數組
- 我們可以通過Array.prototype.slice.call(fakeArray)將偽數組轉變為真正的Array對象: 返回新數組而不會修改原數組
參考: 偽數組
11. undefined和null的區別, 還有undeclared:
- null表示沒有對象, 即此處不該有此值. 典型用法:
-
(1) 作為函數的參數,表示該函數的參數不是對象。
-
(2) 作為對象原型鏈的終點。
- ( 3 ) null可以作為空指針. 只要意在保存對象的值還沒有真正保存對象,就應該明確地讓該對象保存null值.
-
- undefined表示缺少值, 即此處應該有值, 但還未定義.
-
(1)變量被聲明了,但沒有賦值時,就等於undefined。
(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
(3)對象沒有賦值的屬性,該屬性的值為undefined。
(4)函數沒有返回值時,默認返回undefined。
-
- undeclared即為被污染的命名, 訪問沒有被聲明的變量, 則會拋出異常, 終止執行. 即undeclared是一種語法錯誤
12. 事件冒泡機制:
從目標元素開始,往頂層元素傳播。途中如果有節點綁定了相應的事件處理函數,這些函數都會被一次觸發。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)來組織事件的冒泡傳播。
13. 解釋下為什么接下來這段代碼不是 IIFE(立即調用的函數表達式):function foo(){ }();?
答:
而函數定義(語句以function關鍵字開始)是不能被立即執行的,這無疑會導致語法的錯誤(SyntaxError)。當函數定義代碼段包裹在括號內,使解析器可以將之識別為函數表達式,然后調用。IIFE: (function foo(){})()
區分 (function(){})(); 和 (function(){}()); 其實兩者實現效果一樣。
函數字面量:首先聲明一個函數對象,然后執行它。(function () { alert(1); })();
優先表達式:由於Javascript執行表達式是從圓括號里面到外面,所以可以用圓括號強制執行聲明的函數。(function () { alert(2); }());
14. "attribute" 和 "property" 的區別是什么?
答:
DOM元素的attribute和property兩者是不同的東西。attribute翻譯為“特性”,property翻譯為“屬性”。
attribute是一個特性節點,每個DOM元素都有一個對應的attributes屬性來存放所有的attribute節點,attributes是一個類數組的容器,說得准確點就是NameNodeMap,不繼承於Array.prototype,不能直接調用Array的方法。attributes的每個數字索引以名值對(name=”value”)的形式存放了一個attribute節點。<div class="box" id="box" gameid="880">hello</div>
property就是一個屬性,如果把DOM元素看成是一個普通的Object對象,那么property就是一個以名值對(name=”value”)的形式存放在Object中的屬性。要添加和刪除property和普通的對象類似。
很多attribute節點還有一個相對應的property屬性,比如上面的div元素的id和class既是attribute,也有對應的property,不管使用哪種方法都可以訪問和修改。
總之,attribute節點都是在HTML代碼中可見的,而property只是一個普通的名值對屬性。
15. 請指出 document load 和 document ready 兩個事件的區別。
- document.ready和onload的區別——JavaScript文檔加載完成事件。頁面加載完成有兩種事件:
- 一是ready,表示文檔結構已經加載完成(不包含圖片等非文字媒體文件)
- 二是onload,指示頁面包含圖片等文件在內的所有元素都加載完成。
- jQuery中$(function(){/* do something*/});他的作用或者意義就是:在DOM加載完成后就可以可以對DOM進行操作。一般情況先一個頁面響應加載的順序是,域名解析-加載html-加載js和css-加載圖片等其他信息。
16. 什么是use strict? 其好處壞處分別是什么?
答:
在所有的函數 (或者所有最外層函數) 的開始處加入 "use strict"; 指令啟動嚴格模式。
"嚴格模式"有兩種調用方法
1)將"use strict"放在腳本文件的第一行,則整個腳本都將以"嚴格模式"運行。如果這行語句不在第一行,則無效,整個腳本以"正常模式"運行。如果不同模式的代碼文件合並成一個文件,這一點需要特別注意。
2)將整個腳本文件放在一個立即執行的匿名函數之中。
好處
- 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
- 消除代碼運行的一些不安全之處,保證代碼運行的安全;
- 提高編譯器效率,增加運行速度;
- 為未來新版本的Javascript做好鋪墊。
壞處
同樣的代碼,在"嚴格模式"中,可能會有不一樣的運行結果;一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行
17. 瀏覽器端的js包括哪幾個部分?
答: 核心( ECMAScript) , 文檔對象模型(DOM), 瀏覽器對象模型(BOM)
18. DOM包括哪些對象?
答: DOM是針對HTML和XML文檔的一個API(應用程序編程接口). DOM描繪了一個層次化的節點樹, 允許開發人員添加, 移除和修改頁面的某一部分.
- 常用的DOM方法:
- getElementById(id)
- getElementsByTagName()
- appendChild(node)
- removeChild(node)
- replaceChild()
- insertChild()
- createElement()
- createTextNode()
- getAttribute()
- setAttribute()
- 常用的DOM屬性
- innerHTML 節點(元素)的文本值
- parentNode 節點(元素)的父節點
- childNodes
- attributes 節點(元素)的屬性節點
參考: HTML DOM 方法
19. js有哪些基本類型?
答: Undefined, Null, Boolean, Number, String
Object是復雜數據類型, 其本質是由一組無序的名值對組成的.
20. 基本類型與引用類型有什么區別?
答:
- 基本類型如上題所示. 引用類型則有: Object, Array, Date, RegExp, Function
- 存儲
- 基本類型值在內存中占據固定大小的空間,因此被保存在棧內存中
- 引用類型的值是對象, 保存在堆內存中. 包含引用類型的變量實際上包含的並不是對象本身, 而是一個指向改對象的指針
- 復制
- 從一個變量向另一個變量復制基本類型的值, 會創建這個值的一個副本
- 從一個變量向另一個變量復制引用類型的值, 復制的其實是指針, 因此兩個變量最終都指向同一個對象
- 檢測類型
- 確定一個值是哪種基本類型可以用typeof操作符,
- 而確定一個值是哪種引用類型可以使用instanceof操作符
參考: 《JavaScript高級程序設計》
21. 關於js的垃圾收集例程
js是一門具有自動垃圾回收機制的編程語言,開發人員不必關心內存分配和回收問題
- 離開作用域的值將被自動標記為可以回收, 因此將在垃圾收集期間被刪除
- "標記清除"是目前主流的垃圾收集算法, 這種算法的思路是給當前不使用的值加上標記, 然后再回收其內存
- 另一種垃圾收集算法是"引用計數", 這種算法的思想是跟蹤記錄所有值被引用的次數. js引擎目前都不再使用這種算法, 但在IE中訪問非原生JS對象(如DOM元素)時, 這種算法仍然可能會導致問題
- 當代碼中存在循環引用現象時, "引用計數" 算法就會導致問題
- 解除變量的引用不僅有助於消除循環引用現象, 而且對垃圾收集也有好處. 為了確保有效地回收內存, 應該及時解除不再使用的全局對象, 全局對象屬性以及循環引用變量的引用
22. ES5中, 除了函數,什么能夠產生作用域?
答: try-catch 和with延長作用域. 因為他們都會創建一個新的變量對象.
這兩個語句都會在作用域鏈的前端添加一個變量對象. 對with語句來說, 會將指定的對象添加到作用域鏈中. 對catch語句來說, 會創建一個新的變量對象, 其中包含的是被拋出的錯誤對象的聲明.
- 當try代碼塊中發生錯誤時,執行過程會跳轉到catch語句,然后把異常對象推入一個可變對象並置於作用域的頭部。在catch代碼塊內部,函數的所有局部變量將會被放在第二個作用域鏈對象中。請注意,一旦catch語句執行完畢,作用域鏈機會返回到之前的狀態。try-catch語句在代碼調試和異常處理中非常有用,因此不建議完全避免。你可以通過優化代碼來減少catch語句對性能的影響。一個很好的模式是將錯誤委托給一個函數處理
- with(object) {statement}。它的意思是把object添加到作用域鏈的頂端
- e.g.
-
function buildUrl(){ var qs = "?debug=true";
//with接收location對象, 因此其變量對象中就包含了location對象的所有屬性和方法, 而這個變量對象被添加到了作用域鏈的前端 with(location){ //這里的href其實是location.href. 創建了一個名為url的變量, 就成了函數執行環境的一部分 var url = href + qs; } return url;
}
參考: js try、catch、finally語句還有with語句 JavaScript 開發進階:理解 JavaScript 作用域和作用域鏈
23. js有幾種函數調用方式?
答:
- 方法調用模型 var obj = { func : function(){};} obj.func()
- 函數調用模式 var func = function(){} func();
- 構造器調用模式
- apply/ call調用模式
24. 描述事件模型?IE的事件模型是怎樣的?事件代理是什么?事件代理中怎么定位實際事件產生的目標?
答: 捕獲->處於目標->冒泡,IE應該是只有冒泡沒有捕獲。
事件代理就是在父元素上綁定事件來處理,通過event對象的target來定位。
25. js動畫有哪些實現方法?
答: 用定時器 setTimeout和setInterval
26. 還有什么實現動畫的方法?
答:
- js動畫: 使用定時器
- CSS : transition , animation
- transition 包含4種屬性:
transition-delay
transition-duration
transition-property
transition-timing-function
,對應動畫的4種屬性: 延遲、持續時間、對應css屬性和緩動函數, -
transform 包含7種屬性:
animation-name
animation-duration
animation-timing-function
animation-delay
animation-direction
animation-iteration-count
animation-fill-mode
animation-play-state
,它們可以定義動畫名稱,持續時間,緩動函數,動畫延遲,動畫方向,重復次數,填充模式。
- transition 包含4種屬性:
- HTML5 動畫
- canvas
- svg
- webgl
參考自: 前端動畫效果實現的簡單比較
27. 面向對象有哪幾個特點?
答: 封裝, 繼承, 多態
28. 如何判斷屬性來自自身對象還是原型鏈?
答: hasOwnPrototype
29. ES6新特性
答:
1) 箭頭操作符 inputs=>outputs: 操作符左邊是輸入的參數,而右邊則是進行的操作以及返回的值
2) 支持類, 引入了class關鍵字. ES6提供的類實際上就是JS原型模式的包裝
3) 增強的對象字面量.
1. 可以在對象字面量中定義原型 __proto__: xxx //設置其原型為xxx,相當於繼承xxx
2. 定義方法可以不用function關鍵字
3. 直接調用父類方法
4) 字符串模板: ES6中允許使用反引號 ` 來創建字符串,此種方法創建的字符串里面可以包含由美元符號加花括號包裹的變量${vraible}。
5) 自動解析數組或對象中的值。比如若一個函數要返回多個值,常規的做法是返回一個對象,將每個值做為這個對象的屬性返回。但在ES6中,利用解構這一特性,可以直接返回一個數組,然后數組中的值會自動被解析到對應接收該值的變量中。
6) 默認參數值: 現在可以在定義函數的時候指定參數的默認值了,而不用像以前那樣通過邏輯或操作符來達到目的了。
7) 不定參數是在函數中使用命名參數同時接收不定數量的未命名參數。在以前的JavaScript代碼中我們可以通過arguments變量來達到這一目的。不定參數的格式是三個句點后跟代表所有不定參數的變量名。比如下面這個例子中,…x代表了所有傳入add函數的參數。
8) 拓展參數則是另一種形式的語法糖,它允許傳遞數組或者類數組直接做為函數的參數而不用通過apply。
9) let和const關鍵字: 可以把let看成var,只是它定義的變量被限定在了特定范圍內才能使用,而離開這個范圍則無效。const則很直觀,用來定義常量,即無法被更改值的變量。
10) for of值遍歷 每次循環它提供的不是序號而是值。
11) iterator, generator
12) 模塊
13) Map, Set, WeakMap, WeakSet
14) Proxy可以監聽對象身上發生了什么事情,並在這些事情發生后執行一些相應的操作。一下子讓我們對一個對象有了很強的追蹤能力,同時在數據綁定方面也很有用處。
15) Symbols Symbol 通過調用symbol函數產生,它接收一個可選的名字參數,該函數返回的symbol是唯一的。之后就可以用這個返回值做為對象的鍵了。Symbol還可以用來創建私有屬性,外部無法直接訪問由symbol做為鍵的屬性值。
16) Math, Number, String, Object的新API
17) Promises是處理異步操作的一種模式
參考: ES6新特性概覽
30. 如何獲取某個DOM節點,節點遍歷方式
答: getElementById() getElementsByTagName()
節點遍歷: 先序遍歷DOM樹的5種方法
31. 用LESS如何給某些屬性加瀏覽器前綴?
答: 可以自定義一個函數
1
2
3
4
5
6
7
8
|
.border-radius(@values) {
-webkit-border-radius: @values;
-moz-border-radius: @values;
border-radius: @values;
}
div {
.border-radius(10px);
}
|
32. js異步模式如何實現?
33. 事件機制,如何綁定事件處理函數。
34. 圖片預加載的實現
答:
- 使用jQuery圖片預加載插件Lazy Load
- 加載jQuery, 與jquery.lazyload.js
- 設置圖片的占位符為data-original, 給圖片一個特別的標簽,比如class=".lazy"
- 然后延遲加載: $('img.lazy').lazyload();這個函數可以選擇一些參數:
- 圖片預先加載距離:threshold,通過設置這個值,在圖片未出現在可視區域的頂部距離這個值時加載。
- 事件綁定加載的方式:event
- 圖片限定在某個容器內:container
- 使用js實現圖片加載: 就是new一個圖片對象, 綁定onload函數, 賦值url
- 用CSS實現圖片的預加載
- 寫一個CSS樣式設置一批背景圖片,然后將其隱藏
- 改進: 使用js來推遲預加載時間, 防止與頁面其他內容一起加載
- 用Ajax實現預加載
- 其實就是通過ajax請求請求圖片地址. 還可以用這種方式加載css,js文件等
35. 如果在同一個元素上綁定了兩個click事件, 一個在捕獲階段執行, 一個在冒泡階段執行. 那么當觸發click條件時, 會執行幾個事件? 執行順序是什么?
答:
我在回答這個題的時候說是兩個事件, 先執行捕獲的后執行冒泡的. 其實是不對的.
綁定在目標元素上的事件是按照綁定的順序執行的!!!!
即: 綁定在被點擊元素的事件是按照代碼順序發生,其他元素通過冒泡或者捕獲“感知”的事件,按照W3C的標准,先發生捕獲事件,后發生冒泡事件。所有事件的順序是:其他元素捕獲階段事件 -> 本元素代碼順序事件 -> 其他元素冒泡階段事件 。
參考: JavaScript-父子dom同時綁定兩個點擊事件,一個用捕獲,一個用冒泡時執行順序
36. js中怎么實現塊級作用域?
答:
- 使用匿名函數, (立即執行函數)
- (function(){...})()
- 或者es6
-
塊級作用域引入了兩種新的聲明形式,可以用它們定義一個只存在於某個語句塊中的變量或常量.這兩種新的聲明關鍵字為:
let
: 語法上非常類似於var
, 但定義的變量只存在於當前的語句塊中const
: 和let
類似,但聲明的是一個只讀的常量
使用
let
代替var
可以更容易的定義一個只在某個語句塊中存在的局部變量,而不用擔心它和函數體中其他部分的同名變量有沖突.在let
語句內部用var
聲明的變量和在let
語句外部用var
聲明的變量沒什么差別,它們都擁有函數作用域,而不是塊級作用域.
-
37. 構造函數里定義function和使用prototype.func的區別?
答:
1. 直接調用function,每一個類的實例都會拷貝這個函數,弊端就是浪費內存(如上)。prototype方式定義的方式,函數不會拷貝到每一個實例中,所有的實例共享prototype中的定義,節省了內存。
2. 但是如果prototype的屬性是對象的話,所有實例也會共享一個對象(這里問的是函數應該不會出現這個情況),如果其中一個實例改變了對象的值,則所有實例的值都會被改變。同理的話,如果使用prototype調用的函數,一旦改變,所有實例的方法都會改變。——不可以對實例使用prototype屬性,只能對類和函數用。
38. js實現對象的深克隆
答:
因為js中數據類型分為基本數據類型(number, string, boolean, null, undefined)和引用類型值(對象, 數組, 函數). 這兩類對象在復制克隆的時候是有很大區別的. 原始類型存儲的是對象的實際數據, 而對象類型存儲的是對象的引用地址(對象的實際內容單獨存放, 為了減少數據開銷通常放在內存中). 此外, 對象的原型也是引用對象, 它把原型的屬性和方法放在內存中, 通過原型鏈的方式來指向這個內存地址.
於是克隆也會分為兩類:
- 淺度克隆: 原始類型為值傳遞, 對象類型仍為引用傳遞
- 深度克隆: 所有元素或屬性均完全復制, 與原對象完全脫離, 也就是說所有對於新對象的修改都不會反映到原對象中
深度克隆實現:
function clone(obj){ if(typeof(obj)== 'object'){ var result = obj instanceof Array ? [] : {}; for(var i in obj){ var attr = obj[i]; result[i] = arguments.callee(attr); } return result; } else { return obj; } };
參考: JavaScript深克隆 javascript中對象的深度克隆
六、 jQuery問題
七、 一些編程題
1. var obj = {a : 1}; (function (obj) { obj = {a : 2}; })(obj); //問obj怎么變?
答: 外部的obj不變. 因為匿名函數中obj傳入參數等於是創建了一個局部變量obj, 里面的obj指向了一個新的對象 . 如果改成(function () { obj = {a : 2}; })(obj); 就會變了
2. var obj = { a:1, func: function() { (function () { a=2; }(); }} ; obj.fun() //a 怎么變? 匿名函數里的this 是什么?
答: obj里的a不會變. 匿名函數里的this指向全局對象window. 這等於是給window加了一個名為a的屬性
要改變obj中a的值 , 應當:
(function() { this.a = 2}).call(this);
或者obj中定義func : func: function() { var self = this; (function(){self.a=2;})();}
3. 要實現函數內每隔5秒調用自己這個函數,100次以后停止,怎么辦
4. 點擊一個ul的五個li元素,分別彈出他們的序號,怎么做?
想到了用閉包, 但是寫錯了...
一開始是這么寫的
1
2
3
4
5
6
7
|
//注意!!這種寫法是錯誤的!!!<br> for(var i=0; i<oLis.length; i++){
oLis[i].onclick =
function
(){
return
(
function
(j){
alert(j);
})(i);
}
}
|
但是這樣做的話, 點擊所有的li都會彈出最后一個序號. 因為每個li對應的onclick事件的函數, 返回的那個函數的參數還是最后的那個i, 並沒有改變. 應該是這么寫
方法1 :
1
2
3
4
5
6
7
|
for
(
var
i=0; i<oLis.length; i++){
oLis[i].onclick = (
function
(j){
return
function
(){
alert(j);
}
})(i);
}
|
這樣的話, 給每個li綁定onclick事件時, 其實綁的是一個立即執行函數, 這個立即執行函數的參數是i, 因為它是立即執行的, 循環時已經把i的值賦給了li的onclick事件, 所以在外部函數里的i改變后並不會影響i的值.
另一種實現方法:(立即執行函數)
1
2
3
4
5
6
7
|
for
(
var
i=0; i<oLi.length; i++){
(
function
(j){
oLi[j].onclick =
function
(){
alert(j);
};
})(i);
}
|
或者不用閉包
方法2:
var oLi = document.getElementsByTagName('li'); function func(obj,i){ obj.onclick = function(){ alert (i); } } for(var i = 0; i<oLi.length; i++){ func(oLi[i], i); }
方法3: 設置屬性:
1
2
3
4
|
var
oLi = document.getElementsByTagName(
'li'
);
for
(
var
i=0; i<oLi.length; i++){
oLi[i].setAttribute(
"onclick"
,
"alert("
+i+
");"
);
}
|
方法4: 設置index保存
1
2
3
4
5
6
|
for
(
var
i=0; i<oLi.length; i++){
oLi[i].index = i;
oLi[i].onclick =
function
(){
alert(
this
.index);
}
}
|
或者也可以用事件代理來做.
八、js算法題
1. js實現數組去重怎么實現?
方法1. 創建一個新的臨時數組來保存數組中已有的元素
1
2
3
4
5
6
7
8
9
10
11
12
|
var
a =
new
Array(1,2,2,2,2,5,3,2,9,5,6,3);
Array.prototype.unique1 =
function
(){
var
n = [];
//一個新的臨時數組
for
(
var
i=0; i<
this
.length; i++){
//如果把當前數組的第i已經保存進了臨時數組, 那么跳過
if
(n.indexOf(
this
[i]) == -1){
n.push(
this
[i]);
}
}
return
n;
}
console.log(a.unique1());
|
方法2. 使用哈希表存儲已有的元素
1
2
3
4
5
6
7
8
9
10
11
|
Array.prototype.unique2 =
function
(){
var
hash = {},
n = [];
//hash 作為哈希表, n為臨時數組
for
(
var
i=0; i<
this
.length; i++){
if
(!hash[
this
[i]]){
//如果hash表中沒有當前項
hash[
this
[i]] =
true
;
//存入hash表
n.push(
this
[i]);
//當前元素push到臨時數組中
}
}
return
n;
}
|
方法3. 使用indexOf判斷數組元素第一次出現的位置是否為當前位置
1
2
3
4
5
6
7
8
9
10
11
12
|
Array.prototype.unique3 =
function
(){
var
n = [
this
[0]];
for
(
var
i=1; i<
this
.length; i++)
//從第二項開始遍歷
{
//如果當前數組元素在數組中出現的第一次的位置不是i
//說明是重復元素
if
(
this
.indexOf(
this
[i]) == i){
n.push(
this
[i]);
}
}
return
n;
}
|
方法4. 先排序再去重
1
2
3
4
5
6
7
8
9
10
|
Array.prototype.unique4 =
function
(){
this
.sort(
function
(a, b){
return
a - b;});
var
n = [
this
[0]];
for
(
var
i=1; i<
this
.length; i++){
if
(
this
[i] !=
this
[i-1]){
n.push(
this
[i]);
}
}
return
n;
}
|
第一種方法和第三種方法都使用了indexOf(), 這個函數的執行機制也會遍歷數組
第二種方法使用了一個哈希表, 是最快的.
第三種方法也有一個排序的復雜度的計算.
然后做了個測試, 隨機生成100萬個0-1000的數組結果如下:
第三種方法總是第二種方法的將近兩倍, 而第四種方法與數組的范圍有關,
如果是0-100的數組
而如果是0-10000, 方法四看着就效果還不錯了
而第二種方法永遠是最好的, 但是是以空間換時間
全部代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
var
a = [];
for
(
var
i=0; i<1000000; i++){
a.push(Math.ceil(Math.random()*10000));
}
Array.prototype.unique1 =
function
(){
var
n = [];
//一個新的臨時數組
for
(
var
i=0; i<
this
.length; i++){
//如果把當前數組的第i已經保存進了臨時數組, 那么跳過
if
(n.indexOf(
this
[i]) == -1){
n.push(
this
[i]);
}
}
return
n;
}
Array.prototype.unique2 =
function
(){
var
hash = {},
n = [];
//hash 作為哈希表, n為臨時數組
for
(
var
i=0; i<
this
.length; i++){
if
(!hash[
this
[i]]){
//如果hash表中沒有當前項
hash[
this
[i]] =
true
;
//存入hash表
n.push(
this
[i]);
//當前元素push到臨時數組中
}
}
return
n;
}
Array.prototype.unique3 =
function
(){
var
n = [
this
[0]];
for
(
var
i=1; i<
this
.length; i++)
//從第二項開始遍歷
{
//如果當前數組元素在數組中出現的第一次的位置不是i
//說明是重復元素
if
(
this
.indexOf(
this
[i]) == i){
n.push(
this
[i]);
}
}
return
n;
}
Array.prototype.unique4 =
function
(){
this
.sort(
function
(a, b){
return
a - b;});
var
n = [
this
[0]];
for
(
var
i=1; i<
this
.length; i++){
if
(
this
[i] !=
this
[i-1]){
n.push(
this
[i]);
}
}
return
n;
}
var
begin1 =
new
Date();
a.unique1();
var
end1 =
new
Date();
var
begin2 =
new
Date();
a.unique2();
var
end2 =
new
Date();
var
begin3 =
new
Date();
a.unique3();
var
end3 =
new
Date();
var
begin4 =
new
Date();
a.unique4();
var
end4 =
new
Date();
console.log(
"方法一執行時間:"
+ (end1 - begin1));
console.log(
"方法二執行時間:"
+ (end2 - begin2));
console.log(
"方法三執行時間:"
+ (end3 - begin3));
console.log(
"方法四執行時間:"
+ (end4 - begin4));
|
參考: js數組去重
了解前后端分離嗎(當時真不了解,但他細心地給我解釋了一下,還建議我去看淘寶ued團隊的文章)
用什么版本控制工具在用mac嗎用什么來管理各種依賴數組去重position的幾種值css選擇器優先級偽類的用法閉包閉包的實現舉例浮動清除浮動jsonp是啥gulp怎么用,用過啥你覺得你還有什么閃光點我沒有問到的(這個太囧了,我居然反問了面試官你覺得我剛才閃不閃?面試官呵呵呵呵)require的讀取順序圖片輪播(雖然很多面試題都有這個,但是我自己真的沒有實現過,說了一個opacity與setTimeout的組合運用,最后沒有實現到面試官要求的效果,但是他說還行)sass的偽類怎么嵌套jsonp是啥怎么用jsonp發送jsonp時候的那個消息頭長什么樣子?(這個我直接跟他說沒看過不知道)一個文本框,需要兩個控件對里面的值進行控制,一個是+1一個是-1,要求每點擊一次就有個提示框冒出來。而且文本框是可修改的,每次修改也會冒出提示框。(這個我回答的很模糊,我說應該有個監聽的事件的,但是我忘了是啥了,面試官說也行)css定位百度(很驚奇的是面試我的三個面試官都是女生,簡直了)一面css position的幾種值與區別閉包偏向於什么語言?html、css or javascript開發中偏於jQuery還是原生js為什么選擇原生js?最近做過的項目那個系統還在用嗎你是怎么學的?看英文有障礙嗎(卧槽,當時我回答了完全沒有問題,不知道哪里來的自信)二面html5的新功能了解多少說說離線存儲它們與cookie的區別this的理解怎么傳入thisapply和call的區別項目您說說你github上面那個打字機的效果是怎么實現的(這是我fork了一位小伙伴的,但幸好我也花了一點時間弄懂了他的做法,要不然肯定囧死。插播一個很硬的廣告 github.com/sidkwok/typing)前端優化你用過哪些優化(我說了css sprite和減少http請求,順便引出了webpack,但沒想到她也沒有問)gulp你是怎么用的jsonp是啥怎么跨域為什么要跨域怎么學習的position幾種值具體運用是什么display幾種值兼容性你懂多少(我就說了Ajax的還有盒子模型,但她說還有很多,但之前我說了沒有系統地去學過css,都是不會的時候查文檔的,估計因為這樣所以她也沒有追問下去)說說你了解的框架(我說了react和vue)react你覺得怎樣(我說了一些組件化和虛擬dom樹的東西)AngularJS呢(我說沒有學過,但了解過一點,我把我了解的都說了給她聽)兩個的比較為什么你會覺得AngularJS笨重?(也是自己的看法,mvc框架嘛,一整套什么都有)jQuery還是原生js(百度的面試官都問了這個問題,我直接說對於jQuery我並不是很熟悉,因為我更喜歡研究原生js。)為什么選擇原生js(我認為要把原生吃透再去理解其他類庫的話會更好一點,她說也是)三面(二面問面試官我表現怎樣的時候她說,我可以跟你講你已經過了,我的助理會跟你通知的。以為是hr面沒想到還是技術面)介紹自己說說框架比較一下框架你打算怎么去學這些框架聽說你在瀏覽器兼容性這邊學習的不是很好(不慌,她只是建議我這方面其實也很重要)對自己的規划喜歡用什么系統來,我們聊聊人生daocloud一面html語義化h5新標簽es6promisepromise解決了你什么問題跨域的方法jsonp怎么用用過什么庫gulp的插件用過啥webpack為什么要打包 (我說了http請求那點事)介紹一下react組件化是啥你覺的react的優點為什么沒有選擇學習AngularJSflex響應式布局是啥響應式布局是根據什么進行響應css中用什么進行屏幕的判定css中實現陰影的有什么二面點擊a標簽發生了啥http2您說說說說各種框架聊聊AngularJS(說了我的理解,但不怎么了解)那你熟悉哪個框架(正在玩React,vue也懂一點)你給我說說你那個博客生成器(github.com/sidkwok/tech-dairy)(我知道我知道,很多廣告!)聊聊項目聊聊模塊化吧sass你怎么用gulp用過啥介紹一下webpack實現sum(2,3);sum(2,3,4);sum(2,3,4,5);(我用了比較原始的方法,if來判斷)那如果sum里面的參數不確定呢(提取arguments的長度,用for循環)你知道偽數組嗎?ok, 再來一個數組去重吧(這太經典了吧)
- MVC理解
二面問
項目中你解決過哪些比較困難的問題
參考博文: 前端面試問題 不完全的搜狐前端面經 2016美團web前端面試經驗 百度,網易,daocloud,領孚科技,前端開發實習生面經 百度內推兩輪技術面試分享
前端工作面試問題(下) 前端工作面試問題(上) [這個姑娘博客里有超多干貨~]
2016春網易前端暑期實習生筆試面經(二面已掛) 新鮮出爐的網易前端面經
前端網: 前端開發面試題總結--(四)前端綜合
markyun.github:前端開發面試題