1. 跨域問題
同源:兩個文檔需滿足:協(xié)議相同,域名相同,端口相同。
跨域通信 :js進行DOM操作、通信時如果目標與當前窗口不滿足同源條件,瀏覽器為了安全會阻止跨域操作。跨域通信通常有以下方法:
- 如果是log之類的簡單單項通信,新建<img>,<script>,<link>,<iframe>元素,通過src,href屬性設置為目標url。實現跨域請求
- 如果請求json數據,使用<script>進行jsonp請求
- 現代瀏覽器中多窗口通信使用HTML5規(guī)范的
targetWindow.postMessage(data, origin);其中data是需要發(fā)送的對象,origin是目標窗口的origin。window.addEventListener('message', handler, false);handler的event.data是postMessage發(fā)送來的數據,event.origin是發(fā)送窗口的origin,event.source是發(fā)送消息的窗口引用 - 內部服務器代理請求跨域url,然后返回數據
- 跨域請求數據,現代瀏覽器可使用HTML5規(guī)范的CORS功能,只要目標服務器返回HTTP頭部
Access-Control-Allow-Origin: *即可像普通ajax一樣訪問跨域資源
2. call 和 apply 方法是做什么的?有什么區(qū)別?
-
call,apply方法是改變函數體內部 this 的指向。 - 區(qū)別:接收 參數 的方式不同。
call是把參數按順序傳進去,而apply則是把參數放進一個數組中,把數組傳進去。
3. 箭頭函數的 this
箭頭函數 不是function關鍵字定義的函數; 箭頭函數中的 this 在函數被定義的時候就已經 綁定 好了,而 不是 取決于誰調用這個函數,this就指向誰。箭頭函數的this取決于最近的一個非箭頭父級函數的this指向。
var obj = {
a: 10,
b: () => {
console.log(this.a); //undefined
console.log(this); //window
},
c: function() {
console.log(this.a); //10
console.log(this); //obj{...}
}
}
obj.b();
obj.c();
4. css 盒子模型
盒子的組成: margin + border + padding + content
5. css 優(yōu)先級;瀏覽器是如何解析的?
瀏覽器解析css選擇器的規(guī)則是從右向左的。
6. 什么是閉包, 應用場景?
當內部函數被保存到外部時,將會生成閉包。
由于JavaScript的垃圾回收機制,普通函數執(zhí)行完之后,變量就會被直接回收。但是,閉包的方式可以讓變量一直存在,不被回收。
- 閉包的缺點:
閉包會導致原有作用域鏈不釋放,造成內存泄漏。 - 優(yōu)點:
- 實現公有變量。 e.g.: 函數累加器
function add () {
var count = 0;
function demo() {
count ++;
console.log(count);
}
return demo;
}
var counter = add();
counter();
counter();
... ...
function test() {
var num = 100;
function a() {
num++;
console.log(num);
}
function b() {
num --;
console.log(num);
}
return [a, b];
}
var myArr = test();
myArr[0](); // 101
myArr[1](); // 100
- 模塊化開發(fā),防止污染全局變量。
- 可以實現封裝,實現私有化。
閉包應用場景:實現購物車的結賬按鈕,只點一次。
var something= (function() {
var executed = false;
return function() {
if(!executed) {
executed = true;
// do something
}
}
})();
something(); // do something
something(); // nothing happens
7. 什么是 IIFE, 應用場景?
IIFE:立即執(zhí)行函數
IIFE中定義的任何變量和函數,都會在執(zhí)行結束時被銷毀。適合做初始化工作。
(function() {
var a = 123;
var b = 234;
console.log(a+b);
})()
8. constructor 和 prototype 的區(qū)別
任何一個prototype對象都有一個constructor屬性,指向它的構造函數。
9. 如何實現繼承
- 設置原型鏈實現繼承一
缺點: 父類實例屬性為引用類型時,不恰當地修改會導致所有子類被修改。
// Person.prototype --原型
function Person() {};
Person.prototype.name = 'sun';
var ppp = new Person();
- 設置原型鏈實現繼承二: 公有原型
缺點:父類構造函數原型與子類相同。修改子類原型添加方法會修改父類
function Father() {}
function Child() {}
Father.prototype = Child.prototype;
- Object.create() 方式實現類繼承
正確設置原型鏈且避免方法1.2中的缺點;
這個方法會返回一個的 一個新對象, 帶著指定的原型對象和屬性
function Father() {
this.name = 'sun';
this.age = 18;
}
// 父類方法
Father.prototype.getName = function () {
return this.name;
}
function Child() {
Father.call(this); // call father constructor
}
// 子類繼承父類
Child.prototype = Object.create(Father.prototype);
Child.prototype.constructor = Child;
10. 輸入url到渲染的過程
- 在瀏覽器地址欄輸入URL
- 瀏覽器查看緩存,如果請求資源在緩存中并且新鮮,跳轉到轉碼步驟:
如果資源未緩存,發(fā)起新請求; 如果已緩存,檢驗是否足夠新鮮,足夠新鮮直接提供給客戶端,否則與服務器進行驗證。檢驗新鮮通常有兩個HTTP頭進行控制Expires和Cache-Control:
- HTTP1.0提供Expires,值為一個絕對時間表示緩存新鮮日期
- HTTP1.1增加了Cache-Control: max-age=,值為以秒為單位的最大新鮮時間
- 瀏覽器解析URL獲取協(xié)議,主機,端口,path
- 瀏覽器組裝一個HTTP(GET)請求報文
- 瀏覽器獲取主機ip地址,過程如下:
- 瀏覽器緩存
- 本機緩存
- hosts文件
- 路由器緩存
- ISP DNS緩存
- DNS遞歸查詢(可能存在負載均衡導致每次IP不一樣)
-
打開一個socket與目標IP地址,端口建立TCP鏈接,三次握手如下:
- 客戶端發(fā)送一個TCP的SYN=1,Seq=X的包到服務器端口
- 服務器發(fā)回SYN=1, ACK=X+1, Seq=Y的響應包
- 客戶端發(fā)送ACK=Y+1, Seq=Z
- TCP鏈接建立后發(fā)送HTTP請求
- 服務器接受請求并解析,將請求轉發(fā)到服務程序,如虛擬主機使用HTTP Host頭部判斷請求的服務程序
- 服務器檢查HTTP請求頭是否包含緩存驗證信息如果驗證緩存新鮮,返回304等對應狀態(tài)碼
- 處理程序讀取完整請求并準備HTTP響應,可能需要查詢數據庫等操作
- 服務器將響應報文通過TCP連接發(fā)送回瀏覽器
- 瀏覽器接收HTTP響應,然后根據情況選擇關閉TCP連接或者保留重用,關閉TCP連接的四次握手如下:
- 主動方發(fā)送Fin=1, Ack=Z, Seq= X報文
- 被動方發(fā)送ACK=X+1, Seq=Z報文
- 被動方發(fā)送Fin=1, ACK=X, Seq=Y報文
- 主動方發(fā)送ACK=Y, Seq=X報文
- 瀏覽器檢查響應狀態(tài)嗎:是否為1XX,3XX, 4XX, 5XX,這些情況處理與2XX不同
- 如果資源可緩存,進行緩存
- 對響應進行解碼(例如gzip壓縮)
- 根據資源類型決定如何處理(假設資源為HTML文檔)
- 解析HTML文檔,構件DOM樹,下載資源,構造CSSOM樹,執(zhí)行js腳本,這些操作沒有嚴格的先后順序,以下分別解釋
- 構建DOM樹:
- Tokenizing:根據HTML規(guī)范將字符流解析為標記
- Lexing:詞法分析將標記轉換為對象并定義屬性和規(guī)則
- DOM construction:根據HTML標記關系將對象組成DOM樹
- 解析過程中遇到圖片、樣式表、js文件,啟動下載
- 構建CSSOM樹:
- Tokenizing:字符流轉換為標記流
- Node:根據標記創(chuàng)建節(jié)點
- CSSOM:節(jié)點創(chuàng)建CSSOM樹
- 根據DOM樹和CSSOM樹構建渲染樹
- js解析
- 顯示頁面(HTML解析過程中會逐步顯示頁面)
11. sessionStorage,localStorage,cookie區(qū)別
- 都會在瀏覽器端保存,有大小限制,同源限制
- cookie會在請求時發(fā)送到服務器,作為會話標識,服務器可修改cookie;web storage不會發(fā)送到服務器
- cookie有path概念,子路徑可以訪問父路徑cookie,父路徑不能訪問子路徑cookie
- 有效期:cookie在設置的有效期內有效,默認為瀏覽器關閉;sessionStorage在窗口關閉前有效;localStorage長期有效,直到用戶刪除
- 共享:sessionStorage不能共享,localStorage在同源文檔之間共享,cookie在同源且符合path規(guī)則的文檔之間共享
- localStorage的修改會促發(fā)其他文檔窗口的update事件
- cookie有secure屬性要求HTTPS傳輸
瀏覽器不能保存超過300個cookie,單個服務器不能超過20個,每個cookie不能超過4k。web storage大小支持能達到5M
12. css畫三角形
div1{
border-style: solid;
border-width: 0px 0px 100px 100px;
border-color: transparent transparent blue transparent;
width: 0px;
height: 0px;
}
13. offsetHeight, scrollHeight, clientHeight 的區(qū)別
-
offsetWidth/offsetHeight返回值包含content + padding + border,效果與e.getBoundingClientRect()相同 -
clientWidth/clientHeight返回值只包含content + padding,如果有滾動條,也不包含滾動條 -
scrollWidth/scrollHeight返回值包含content + padding + 溢出內容的尺寸
14. 右邊固定寬度,左邊自適應
<style>
body {
display: flex;
}
.left{
background-color: pink;
height: 200px;
flex: 1;
}
.right{
background: orange;
height: 200px;
width: 100px;
}
</style>
...
<body>
<div class="left"></div>
<div class="right"></div>
</body>
<style>
div {
height: 200px;
}
.left{
background-color: pink;
margin-right: 200px;
}
.right{
background: orange;
width: 200px;
float: right;
}
</style>
<body>
<div class="right"></div>
<div class="left"></div>
</body>
15. 垂直水平居中
- 如果需要居中的元素為常規(guī)流中
inline元素,為父元素設置text-align: center;即可實現 - 如果需要居中的元素為常規(guī)流中
block元素,1)為元素設置寬度,2)設置margin: 0 auto;
<style>
.center {
width: 400px;
height: 300px;
border: 1px solid black;
margin: 0 auto;
}
</style>
... ...
<body>
<div class="center"></div>
</body>
- 定位,1)為元素設置寬度,2)position: relative;,3)浮動方向偏移量(left/ top)設置為50%,4)浮動方向上的margin設置為元素寬度一半乘以-1, 元素高度的一半乘以 -1
<style>
.container {
height: 100vh;
position: relative;
}
.center {
width: 500px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
border: 1px solid red;
margin: -150px 0 0 -200px;
}
</style>
...
<body>
<div class="container">
<div class="center"></div>
</div>
</body>
- 使用CSS3中的
transform的translate屬性
.container {
height: 100vh;
position: relative;
}
.center {
width: 500px;
height: 300px;
border: 1px solid orange;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
- flex布局
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.center {
width: 500px;
height: 300px;
border: 1px solid black;
}
16. 清除浮動
- 使用偽元素選擇器和隔墻法
設置添加的子元素為空,為塊級元素,高度為0,子元素看不見,并且設置clear屬性。
.box1::after{
content: "";
height: 0;
display:block;
clear: both;
}
兼容問題:IE6 并不支持。但是設置以下代碼,IE6就能支持。
.box1{
*zoom:1;
}
- overflow: hidden;
作用: 1. 可以將超出標簽范圍的內容裁剪掉; 2. 清除浮動; 3. 通過設置這個屬性讓嵌套的兩個盒子,里面的盒子設置margin-top之后,外面的盒子不被頂下來。
給第一個盒子添加 overflow: hidden;即可。
17. 前端需要注意的SEO
- 合理的title、description、keywords:搜索對著三項的權重逐個減小,title值強調重點即可,重要關鍵詞出現不要超過2次,而且要靠前,不同頁面title要有所不同;description把頁面內容高度概括,長度合適,不可過分堆砌關鍵詞,不同頁面description有所不同;keywords列舉出重要關鍵詞即可
- 語義化的HTML代碼,符合W3C規(guī)范:語義化代碼讓搜索引擎容易理解網頁
- 重要內容HTML代碼放在最前:搜索引擎抓取HTML順序是從上到下,有的搜索引擎對抓取長度有限制,保證重要內容一定會被抓取
- 重要內容不要用js輸出:爬蟲不會執(zhí)行js獲取內容
- 少用iframe:搜索引擎不會抓取iframe中的內容
- 非裝飾性圖片必須加alt
- 提高網站速度:網站速度是搜索引擎排序的一個重要指標
18. get 和 post 的區(qū)別
如果什么前提都沒有,只考慮語法來說,這兩個方式沒什么區(qū)別。
如果是基于RFC規(guī)范的,那么 GET 和 POST 有不同的語義:
- GET方式用作獲取信息; POST方式用作發(fā)送信息。
- GET的數據在URL中對所有人都是可見的;POST的數據不會顯示在URL中。
- GET對數據長度有限制,當發(fā)送數據時,GET方法向URL添加數據,最大長度是2048個字符。 POST無限制。
- GET 后退按鈕/ 刷新 無影響; POST數據會被重新提交
- GET 編碼類型
application/x-www-form-url; POST 編碼類型encodedapplication/x-www-form-urlencoded或者multipart/form-data。 - 與POST相比,GET的安全性較差。因為發(fā)送的數據是URL的一部分。
- GET歷史參數會保留在瀏覽器歷史中。POST參數不會保存在瀏覽器歷史中。
19. 如何優(yōu)化網站的性能
content方面:
- 減少HTTP請求:合并文件、CSS精靈
- 減少DNS查詢:DNS查詢完成之前瀏覽器不能從這個主機下載任何任何文件。方法:DNS緩存、將資源分布到恰當數量的主機名,平衡并行下載和DNS查詢
- 避免重定向:多余的中間訪問
- 使Ajax可緩存
- 非必須組件延遲加載
- 未來所需組件預加載
- 減少DOM元素數量
- 減少iframe數量
css/ js方面:
- 將樣式表放到頁面頂部
- 不使用CSS表達式
- 將件腳本放到頁面底部
- 將css和javascript從外部引入
- 壓縮javascript和css
- 減少DOM訪問
- 合理設計事件監(jiān)聽器
20. 什么是漸進增強?
漸進增強是指在web設計時強調可訪問性、語義化HTML標簽、外部樣式表和腳本。保證所有人都能訪問頁面的基本內容和功能同時為高級瀏覽器和高帶寬用戶提供更好的用戶體驗。核心原則如下:
- 所有瀏覽器都必須能訪問基本內容
- 所有瀏覽器都必須能使用基本功能
- 所有內容都包含在語義化標簽中
- 通過外部CSS提供增強的布局
- 通過非侵入式、外部javascript提供增強功能
21. arguments 是數組嗎?怎么轉為數組
arguments是類數組。長得像數組,也可以當數組用,但是它 不是 數組。因為數組有的方法它全沒有。類數組本身是個對象。
類數組的組成:
- 屬性要為索引屬性
- 必須有l(wèi)ength屬性,最好加上push方法
- 如果加上了 splice方法,這個對象就看上去長得和數組一樣了
Array.prototype.splice
題目: obj最后長啥樣?
var obj = {
"2" : "a",
"3" : "b",
"length" : 2,
"push": Array.prototype.push
}
obj.push('c');
obj.push('d');
答案:{ "2" : "c", "3" : "d", "length": 4 }
原理:
Array.prototype.push = function(target) {
arr[arr.length] = target;
arr.length ++;
}
22. 事件委派
指的就是js事件冒泡:事件的向上傳導,當后代元素的事件被觸發(fā)時,其祖先元素的相同時間也會被觸發(fā);
23. https/ http2/ http狀態(tài)碼/ OSI七層協(xié)議 / cdn及cdns
24. 主流瀏覽器及其內核
- IE
內核: Trident - Google Chrome
內核:Webkit / blink - Firefox
內核:Gecko - Safari
內核:Webkit - Opera
內核:presto