1、基礎javascript篇
1. get請求傳參長度的誤區
誤區:咱們常常說get請求參數的大小存在限制,而post請求的參數大小是無限制的。html5
實際上HTTP 協議從未規定 GET/POST 的請求長度限制是多少。對get請求參數的限制是來源與瀏覽器或web服務器,瀏覽器或web服務器限制了url的長度。爲了明確這個概念,咱們必須再次強調下面幾點:java
- HTTP 協議 未規定 GET 和POST的長度限制
- GET的最大長度顯示是由於 瀏覽器和 web服務器限制了 URI的長度
- 不一樣的瀏覽器和WEB服務器,限制的最大長度不同
- 要支持IE,則最大長度爲2083byte,若只支持Chrome,則最大長度 8182byte
2. 補充get和post請求在緩存方面的區別
post/get的請求區別,具體再也不贅述。node
補充補充一個get和post在緩存方面的區別:ios
- get請求相似於查找的過程,用戶獲取數據,能夠不用每次都與數據庫鏈接,因此可使用緩存。
- post不一樣,post作的通常是修改和刪除的工做,因此必須與數據庫交互,因此不能使用緩存。所以get請求適合於請求緩存。
3. 閉包
一句話能夠歸納:閉包就是可以讀取其餘函數內部變量的函數,或者子函數在外調用,子函數所在的父函數的做用域不會被釋放。css3
4. 類的建立和繼承
(1)類的建立(es5):new一個function,在這個function的prototype裏面增長屬性和方法。
下面來建立一個Animal類:
// 定義一個動物類
function Animal (name) {
// 屬性
this.name = name || 'Animal';
// 實例方法
this.sleep = function(){
console.log(this.name + '正在睡覺!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
複製代碼
這樣就生成了一個Animal類,實力化生成對象後,有方法和屬性。
(2)類的繼承——原型鏈繼承
--原型鏈繼承
function Cat(){ }
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
複製代碼
- 介紹:在這裏咱們能夠看到new了一個空對象,這個空對象指向Animal而且Cat.prototype指向了這個空對象,這種就是基於原型鏈的繼承。
- 特色:基於原型鏈,既是父類的實例,也是子類的實例
- 缺點:沒法實現多繼承
(3)構造繼承:使用父類的構造函數來加強子類實例,等因而複製父類的實例屬性給子類(沒用到原型)
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
複製代碼
- 特色:能夠實現多繼承
- 缺點:只能繼承父類實例的屬性和方法,不能繼承原型上的屬性和方法。
(4)實例繼承和拷貝繼承
實例繼承:爲父類實例添加新特性,做爲子類實例返回
拷貝繼承:拷貝父類元素上的屬性和方法
上述兩個實用性不強,不一一舉例。
(5)組合繼承:至關於構造繼承和原型鏈繼承的組合體。經過調用父類構造,繼承父類的屬性並保留傳參的優勢,而後經過將父類實例做爲子類原型,實現函數複用
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
複製代碼
- 特色:能夠繼承實例屬性/方法,也能夠繼承原型屬性/方法
- 缺點:調用了兩次父類構造函數,生成了兩份實例
(6)寄生組合繼承:經過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 建立一個沒有實例方法的類
var Super = function(){};
Super.prototype = Animal.prototype;
//將實例做爲子類的原型
Cat.prototype = new Super();
})();
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
複製代碼
- 較爲推薦
5. 如何解決異步回調地獄
promise、generator、async/await
6. 說說前端中的事件流
HTML中與javascript交互是經過事件驅動來實現的,例如鼠標點擊事件onclick、頁面的滾動事件onscroll等等,能夠向文檔或者文檔中的元素添加事件偵聽器來預訂事件。想要知道這些事件是在何時進行調用的,就須要瞭解一下「事件流」的概念。
什麼是事件流:事件流描述的是從頁面中接收事件的順序,DOM2級事件流包括下面幾個階段。
- 事件捕獲階段
- 處於目標階段
- 事件冒泡階段
addEventListener:addEventListener 是DOM2 級事件新增的指定事件處理程序的操做,這個方法接收3個參數:要處理的事件名、做爲事件處理程序的函數和一個布爾值。最後這個布爾值參數若是是true,表示在捕獲階段調用事件處理程序;若是是false,表示在冒泡階段調用事件處理程序。
IE只支持事件冒泡。
7. 如何讓事件先冒泡後捕獲
在DOM標準事件模型中,是先捕獲後冒泡。可是若是要實現先冒泡後捕獲的效果,對於同一個事件,監聽捕獲和冒泡,分別對應相應的處理函數,監聽到捕獲事件,先暫緩執行,直到冒泡事件被捕獲後再執行捕獲之間。
8. 事件委託
-
簡介:事件委託指的是,不在事件的發生地(直接dom)上設置監聽函數,而是在其父元素上設置監聽函數,經過事件冒泡,父元素能夠監聽到子元素上事件的觸發,經過判斷事件發生元素DOM的類型,來作出不一樣的響應。
-
舉例:最經典的就是ul和li標籤的事件監聽,好比咱們在添加事件時候,採用事件委託機制,不會在li標籤上直接添加,而是在ul父元素上添加。
-
好處:比較合適動態元素的綁定,新添加的子元素也會有監聽函數,也能夠有事件觸發機制。
9. 圖片的懶加載和預加載
-
預加載:提早加載圖片,當用戶須要查看時可直接從本地緩存中渲染。
-
懶加載:懶加載的主要目的是做爲服務器前端的優化,減小請求數或延遲請求數。
兩種技術的本質:二者的行爲是相反的,一個是提早加載,一個是遲緩甚至不加載。 懶加載對服務器前端有必定的緩解壓力做用,預加載則會增長服務器前端壓力。
10. mouseover和mouseenter的區別
-
mouseover:當鼠標移入元素或其子元素都會觸發事件,因此有一個重複觸發,冒泡的過程。對應的移除事件是mouseout
-
mouseenter:當鼠標移除元素自己(不包含元素的子元素)會觸發事件,也就是不會冒泡,對應的移除事件是mouseleave
11. js的new操做符作了哪些事情
new 操做符新建了一個空對象,這個對象原型指向構造函數的prototype,執行構造函數後返回這個對象。
12.改變函數內部this指針的指向函數(bind,apply,call的區別)
-
經過apply和call改變函數的this指向,他們兩個函數的第一個參數都是同樣的表示要改變指向的那個對象,第二個參數,apply是數組,而call則是arg1,arg2...這種形式。
-
經過bind改變this做用域會返回一個新的函數,這個函數不會立刻執行。
13. js的各類位置,好比clientHeight,scrollHeight,offsetHeight ,以及scrollTop, offsetTop,clientTop的區別?
-
clientHeight:表示的是可視區域的高度,不包含border和滾動條
-
offsetHeight:表示可視區域的高度,包含了border和滾動條
-
scrollHeight:表示了全部區域的高度,包含了由於滾動被隱藏的部分。
-
clientTop:表示邊框border的厚度,在未指定的狀況下通常爲0
-
scrollTop:滾動後被隱藏的高度,獲取對象相對於由offsetParent屬性指定的父座標(css定位的元素或body元素)距離頂端的高度。
14. js拖拽功能的實現
-
首先是三個事件,分別是mousedown,mousemove,mouseup 當鼠標點擊按下的時候,須要一個tag標識此時已經按下,能夠執行mousemove裏面的具體方法。
-
clientX,clientY標識的是鼠標的座標,分別標識橫座標和縱座標,而且咱們用offsetX和offsetY來表示元素的元素的初始座標,移動的舉例應該是:
鼠標移動時候的座標-鼠標按下去時候的座標。
也就是說定位信息爲:
鼠標移動時候的座標-鼠標按下去時候的座標+元素初始狀況下的offetLeft.
-
還有一點也是原理性的東西,也就是拖拽的同時是絕對定位,咱們改變的是絕對定位條件下的left 以及top等等值。
補充:也能夠經過html5的拖放(Drag 和 drop)來實現
2、進階javascript篇
1.本身實現一個bind函數
原理:經過apply或者call方法來實現。
(1)初始版本
Function.prototype.bind=function(obj,arg){
var arg=Array.prototype.slice.call(arguments,1);
var context=this;
return function(newArg){
arg=arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj,arg);
}
}
複製代碼
(2) 考慮到原型鏈
爲何要考慮?由於在new 一個bind過生成的新函數的時候,必須的條件是要繼承原函數的原型
Function.prototype.bind=function(obj,arg){
var arg=Array.prototype.slice.call(arguments,1);
var context=this;
var bound=function(newArg){
arg=arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj,arg);
}
var F=function(){}
//這裏須要一個寄生組合繼承
F.prototype=context.prototype;
bound.prototype=new F();
return bound;
}
複製代碼
2.用setTimeout來實現setInterval
(1)用setTimeout()方法來模擬setInterval()與setInterval()之間的什麼區別?
首先來看setInterval的缺陷,使用setInterval()建立的定時器確保了定時器代碼規則地插入隊列中。這個問題在於:若是定時器代碼在代碼再次添加到隊列以前還沒完成執行,結果就會致使定時器代碼連續運行好幾回。而之間沒有間隔。不過幸運的是:javascript引擎足夠聰明,可以避免這個問題。當且僅當沒有該定時器的如何代碼實例時,纔會將定時器代碼添加到隊列中。這確保了定時器代碼加入隊列中最小的時間間隔爲指定時間。
這種重複定時器的規則有兩個問題:1.某些間隔會被跳過 2.多個定時器的代碼執行時間可能會比預期小。
下面舉例子說明:
假設,某個onclick事件處理程序使用啦setInterval()來設置了一個200ms的重複定時器。若是事件處理程序花了300ms多一點的時間完成。
![2018-07-10 11 36 43](http://static.javashuo.com/static/loading.gif)
這個例子中的第一個定時器是在205ms處添加到隊列中,可是要過300ms才能執行。在405ms又添加了一個副本。在一個間隔,605ms處,第一個定時器代碼還在執行中,並且隊列中已經有了一個定時器實例,結果是605ms的定時器代碼不會添加到隊列中。結果是在5ms處添加的定時器代碼執行結束後,405處的代碼當即執行。
function say(){
//something
setTimeout(say,200);
}
setTimeout(say,200)
複製代碼
或者
setTimeout(function(){
//do something
setTimeout(arguments.callee,200);
},200);
複製代碼
3.js怎麼控制一次加載一張圖片,加載完後再加載下一張
(1)方法1
<script type="text/javascript">
var obj=new Image();
obj.src="http://www.phpernote.com/uploadfiles/editor/201107240502201179.jpg";
obj.onload=function(){
alert('圖片的寬度爲:'+obj.width+';圖片的高度爲:'+obj.height);
document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />";
}
</script>
<div id="mypic">onloading……</div>
複製代碼
(2)方法2
<script type="text/javascript">
var obj=new Image();
obj.src="http://www.phpernote.com/uploadfiles/editor/201107240502201179.jpg";
obj.onreadystatechange=function(){
if(this.readyState=="complete"){
alert('圖片的寬度爲:'+obj.width+';圖片的高度爲:'+obj.height);
document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />";
}
}
</script>
<div id="mypic">onloading……</div>
複製代碼
3.代碼的執行順序
setTimeout(function(){console.log(1)},0);
new Promise(function(resolve,reject){
console.log(2);
resolve();
}).then(function(){console.log(3)
}).then(function(){console.log(4)});
process.nextTick(function(){console.log(5)});
console.log(6);
//輸出2,6,5,3,4,1
複製代碼
爲何呢?具體請參考個人文章: 從promise、process.nextTick、setTimeout出發,談談Event Loop中的Job queue
4.如何實現sleep的效果(es5或者es6)
(1)while循環的方式
function sleep(ms){
var start=Date.now(),expire=start+ms;
while(Date.now()<expire);
console.log('1111');
return;
}
複製代碼
執行sleep(1000)以後,休眠了1000ms以後輸出了1111。上述循環的方式缺點很明顯,容易形成死循環。
(2)經過promise來實現
function sleep(ms){
var temple=new Promise(
(resolve)=>{
console.log(111);setTimeout(resolve,ms)
});
return temple
}
sleep(500).then(function(){
//console.log(222)
})
//先輸出了111,延遲500ms後輸出222
複製代碼
(3)經過async封裝
function sleep(ms){
return new Promise((resolve)=>setTimeout(resolve,ms));
}
async function test(){
var temple=await sleep(1000);
console.log(1111)
return temple
}
test();
//延遲1000ms輸出了1111
複製代碼
####(4).經過generate來實現
function* sleep(ms){
yield new Promise(function(resolve,reject){
console.log(111);
setTimeout(resolve,ms);
})
}
sleep(500).next().value.then(function(){console.log(2222)})
複製代碼
5.簡單的實現一個promise
首先明確什麼是promiseA+規範,參考規範的地址:
如何實現一個promise,參考個人文章:
通常不會問的很詳細,只要能寫出上述文章中的v1.0版本的簡單promise便可。
6.Function._proto_(getPrototypeOf)是什麼?
獲取一個對象的原型,在chrome中能夠經過__proto__的形式,或者在ES6中能夠經過Object.getPrototypeOf的形式。
那麼Function.proto是什麼麼?也就是說Function由什麼對象繼承而來,咱們來作以下判別。
Function.__proto__==Object.prototype //false
Function.__proto__==Function.prototype//true
複製代碼
咱們發現Function的原型也是Function。
咱們用圖能夠來明確這個關係:
![2018-07-10 2 38 27](http://static.javashuo.com/static/loading.gif)
7.實現js中全部對象的深度克隆(包裝對象,Date對象,正則對象)
經過遞歸能夠簡單實現對象的深度克隆,可是這種方法無論是ES6仍是ES5實現,都有一樣的缺陷,就是隻能實現特定的object的深度複製(好比數組和函數),不能實現包裝對象Number,String , Boolean,以及Date對象,RegExp對象的複製。
(1)前文的方法
function deepClone(obj){
var newObj= obj instanceof Array?[]:{};
for(var i in obj){
newObj[i]=typeof obj[i]=='object'?
deepClone(obj[i]):obj[i];
}
return newObj;
}
複製代碼
這種方法能夠實現通常對象和數組對象的克隆,好比:
var arr=[1,2,3];
var newArr=deepClone(arr);
// newArr->[1,2,3]
var obj={
x:1,
y:2
}
var newObj=deepClone(obj);
// newObj={x:1,y:2}
複製代碼
可是不能實現例如包裝對象Number,String,Boolean,以及正則對象RegExp和Date對象的克隆,好比:
//Number包裝對象
var num=new Number(1);
typeof num // "object"
var newNum=deepClone(num);
//newNum -> {} 空對象
//String包裝對象
var str=new String("hello");
typeof str //"object"
var newStr=deepClone(str);
//newStr-> {0:'h',1:'e',2:'l',3:'l',4:'o'};
//Boolean包裝對象
var bol=new Boolean(true);
typeof bol //"object"
var newBol=deepClone(bol);
// newBol ->{} 空對象
....
複製代碼
(2)valueof()函數
全部對象都有valueOf方法,valueOf方法對於:若是存在任意原始值,它就默認將對象轉換爲表示它的原始值。對象是複合值,並且大多數對象沒法真正表示爲一個原始值,所以默認的valueOf()方法簡單地返回對象自己,而不是返回一個原始值。數組、函數和正則表達式簡單地繼承了這個默認方法,調用這些類型的實例的valueOf()方法只是簡單返回這個對象自己。
對於原始值或者包裝類:
function baseClone(base){
return base.valueOf();
}
//Number
var num=new Number(1);
var newNum=baseClone(num);
//newNum->1
//String
var str=new String('hello');
var newStr=baseClone(str);
// newStr->"hello"
//Boolean
var bol=new Boolean(true);
var newBol=baseClone(bol);
//newBol-> true
複製代碼
其實對於包裝類,徹底能夠用=號來進行克隆,其實沒有深度克隆一說,
這裏用valueOf實現,語法上比較符合規範。
對於Date類型:
由於valueOf方法,日期類定義的valueOf()方法會返回它的一個內部表示:1970年1月1日以來的毫秒數.所以咱們能夠在Date的原型上定義克隆的方法:
Date.prototype.clone=function(){
return new Date(this.valueOf());
}
var date=new Date('2010');
var newDate=date.clone();
// newDate-> Fri Jan 01 2010 08:00:00 GMT+0800
複製代碼
對於正則對象RegExp:
RegExp.prototype.clone = function() {
var pattern = this.valueOf();
var flags = '';
flags += pattern.global ? 'g' : '';
flags += pattern.ignoreCase ? 'i' : '';
flags += pattern.multiline ? 'm' : '';
return new RegExp(pattern.source, flags);
};
var reg=new RegExp('/111/');
var newReg=reg.clone();
//newReg-> /\/111\//
複製代碼
8.簡單實現Node的Events模塊
簡介:觀察者模式或者說訂閱模式,它定義了對象間的一種一對多的關係,讓多個觀察者對象同時監聽某一個主題對象,當一個對象發生改變時,全部依賴於它的對象都將獲得通知。
node中的Events模塊就是經過觀察者模式來實現的:
var events=require('events');
var eventEmitter=new events.EventEmitter();
eventEmitter.on('say',function(name){
console.log('Hello',name);
})
eventEmitter.emit('say','Jony yu');
複製代碼
這樣,eventEmitter發出say事件,經過On接收,而且輸出結果,這就是一個訂閱模式的實現,下面咱們來簡單的實現一個Events模塊的EventEmitter。
(1)實現簡單的Event模塊的emit和on方法
function Events(){
this.on=function(eventName,callBack){
if(!this.handles){
this.handles={};
}
if(!this.handles[eventName]){
this.handles[eventName]=[];
}
this.handles[eventName].push(callBack);
}
this.emit=function(eventName,obj){
if(this.handles[eventName]){
for(var i=0;o<this.handles[eventName].length;i++){
this.handles[eventName][i](obj);
}
}
}
return this;
}
複製代碼
這樣咱們就定義了Events,如今咱們能夠開始來調用:
var events=new Events();
events.on('say',function(name){
console.log('Hello',nama)
});
events.emit('say','Jony yu');
//結果就是經過emit調用以後,輸出了Jony yu
複製代碼
(2)每一個對象是獨立的
由於是經過new的方式,每次生成的對象都是不相同的,所以:
var event1=new Events();
var event2=new Events();
event1.on('say',function(){
console.log('Jony event1');
});
event2.on('say',function(){
console.log('Jony event2');
})
event1.emit('say');
event2.emit('say');
//event一、event2之間的事件監聽互相不影響
//輸出結果爲'Jony event1' 'Jony event2'
複製代碼
9.箭頭函數中this指向舉例
var a=11;
function test2(){
this.a=22;
let b=()=>{console.log(this.a)}
b();
}
var x=new test2();
//輸出22
複製代碼
定義時綁定。
3、http、html和瀏覽器篇
1.http和https
https的SSL加密是在傳輸層實現的。
(1)http和https的基本概念
http: 超文本傳輸協議,是互聯網上應用最爲普遍的一種網絡協議,是一個客戶端和服務器端請求和應答的標準(TCP),用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它可使瀏覽器更加高效,使網絡傳輸減小。
https: 是以安全爲目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL。
https協議的主要做用是:創建一個信息安全通道,來確保數組的傳輸,確保網站的真實性。
(2)http和https的區別?
http傳輸的數據都是未加密的,也就是明文的,網景公司設置了SSL協議來對http協議傳輸的數據進行加密處理,簡單來講https協議是由http和ssl協議構建的可進行加密傳輸和身份認證的網絡協議,比http協議的安全性更高。 主要的區別以下:
- Https協議須要ca證書,費用較高。
- http是超文本傳輸協議,信息是明文傳輸,https則是具備安全性的ssl加密傳輸協議。
- 使用不一樣的連接方式,端口也不一樣,通常而言,http協議的端口爲80,https的端口爲443
- http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
(3)https協議的工做原理
客戶端在使用HTTPS方式與Web服務器通訊時有如下幾個步驟,如圖所示。
- 客戶使用https url訪問服務器,則要求web 服務器創建ssl連接。
- web服務器接收到客戶端的請求以後,會將網站的證書(證書中包含了公鑰),返回或者說傳輸給客戶端。
- 客戶端和web服務器端開始協商SSL連接的安全等級,也就是加密等級。
- 客戶端瀏覽器經過雙方協商一致的安全等級,創建會話密鑰,而後經過網站的公鑰來加密會話密鑰,並傳送給網站。
- web服務器經過本身的私鑰解密出會話密鑰。
- web服務器經過會話密鑰加密與客戶端之間的通訊。
(4)https協議的優勢
- 使用HTTPS協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
- HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全,可防止數據在傳輸過程當中不被竊取、改變,確保數據的完整性。
- HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增長了中間人攻擊的成本。
- 谷歌曾在2014年8月份調整搜索引擎算法,並稱「比起同等HTTP網站,採用HTTPS加密的網站在搜索結果中的排名將會更高」。
(5)https協議的缺點
- https握手階段比較費時,會使頁面加載時間延長50%,增長10%~20%的耗電。
- https緩存不如http高效,會增長數據開銷。
- SSL證書也須要錢,功能越強大的證書費用越高。
- SSL證書須要綁定IP,不能再同一個ip上綁定多個域名,ipv4資源支持不了這種消耗。
2.tcp三次握手,一句話歸納
客戶端和服務端都須要直到各自可收發,所以須要三次握手。
簡化三次握手:
![2018-07-10 3 42 11](http://static.javashuo.com/static/loading.gif)
從圖片能夠獲得三次握手能夠簡化爲:C發起請求鏈接S確認,也發起鏈接C確認咱們再看看每次握手的做用:第一次握手:S只能夠確認 本身能夠接受C發送的報文段第二次握手:C能夠確認 S收到了本身發送的報文段,而且能夠確認 本身能夠接受S發送的報文段第三次握手:S能夠確認 C收到了本身發送的報文段
3.TCP和UDP的區別
(1)TCP是面向鏈接的,udp是無鏈接的即發送數據前不須要先創建連接。
(2)TCP提供可靠的服務。也就是說,經過TCP鏈接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付。 而且由於tcp可靠,面向鏈接,不會丟失數據所以適合大數據量的交換。
(3)TCP是面向字節流,UDP面向報文,而且網絡出現擁塞不會使得發送速率下降(所以會出現丟包,對實時的應用好比IP電話和視頻會議等)。
(4)TCP只能是1對1的,UDP支持1對1,1對多。
(5)TCP的首部較大爲20字節,而UDP只有8字節。
(6)TCP是面向鏈接的可靠性傳輸,而UDP是不可靠的。
4.WebSocket的實現和應用
(1)什麼是WebSocket?
WebSocket是HTML5中的協議,支持持久連續,http協議不支持持久性鏈接。Http1.0和HTTP1.1都不支持持久性的連接,HTTP1.1中的keep-alive,將多個http請求合併爲1個
(2)WebSocket是什麼樣的協議,具體有什麼優勢?
- HTTP的生命週期經過Request來界定,也就是Request一個Response,那麼在Http1.0協議中,此次Http請求就結束了。在Http1.1中進行了改進,是的有一個connection:Keep-alive,也就是說,在一個Http鏈接中,能夠發送多個Request,接收多個Response。可是必須記住,在Http中一個Request只能對應有一個Response,並且這個Response是被動的,不能主動發起。
- WebSocket是基於Http協議的,或者說借用了Http協議來完成一部分握手,在握手階段與Http是相同的。咱們來看一個websocket握手協議的實現,基本是2個屬性,upgrade,connection。
基本請求以下:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
複製代碼
多了下面2個屬性:
Upgrade:webSocket
Connection:Upgrade
告訴服務器發送的是websocket
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
複製代碼
5.HTTP請求的方式,HEAD方式
- head:相似於get請求,只不過返回的響應中沒有具體的內容,用戶獲取報頭
- options:容許客戶端查看服務器的性能,好比說服務器支持的請求方式等等。
6.一個圖片url訪問後直接下載怎樣實現?
請求的返回頭裏面,用於瀏覽器解析的重要參數就是OSS的API文檔裏面的返回http頭,決定用戶下載行爲的參數。
下載的狀況下:
1. x-oss-object-type:
Normal
2. x-oss-request-id:
598D5ED34F29D01FE2925F41
3. x-oss-storage-class:
Standard
複製代碼
7.web Quality (無障礙)
可以被殘障人士使用的網站才能稱得上一個易用的(易訪問的)網站。 殘障人士指的是那些帶有殘疾或者身體不健康的用戶。
使用alt屬性:
<img src="person.jpg" alt="this is a person"/>
複製代碼
有時候瀏覽器會沒法顯示圖像。具體的緣由有:
- 用戶關閉了圖像顯示
- 瀏覽器是不支持圖形顯示的迷你瀏覽器
- 瀏覽器是語音瀏覽器(供盲人和弱視人羣使用) 若是您使用了 alt 屬性,那麼瀏覽器至少能夠顯示或讀出有關圖像的描述。
8.幾個很實用的BOM屬性對象方法?
什麼是Bom? Bom是瀏覽器對象。有哪些經常使用的Bom屬性呢?
(1)location對象
location.href-- 返回或設置當前文檔的URL location.search -- 返回URL中的查詢字符串部分。例如 http://www.dreamdu.com/dreamdu.php?id=5&name=dreamdu 返回包括(?)後面的內容?id=5&name=dreamdu location.hash -- 返回URL#後面的內容,若是沒有#,返回空 location.host -- 返回URL中的域名部分,例如www.dreamdu.com location.hostname -- 返回URL中的主域名部分,例如dreamdu.com location.pathname -- 返回URL的域名後的部分。例如 http://www.dreamdu.com/xhtml/ 返回/xhtml/ location.port -- 返回URL中的端口部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回8080 location.protocol -- 返回URL中的協議部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回(//)前面的內容http: location.assign -- 設置當前文檔的URL location.replace() -- 設置當前文檔的URL,而且在history對象的地址列表中移除這個URL location.replace(url); location.reload() -- 重載當前頁面
(2)history對象
history.go() -- 前進或後退指定的頁面數 history.go(num); history.back() -- 後退一頁 history.forward() -- 前進一頁
(3)Navigator對象
navigator.userAgent -- 返回用戶代理頭的字符串表示(就是包括瀏覽器版本信息等的字符串) navigator.cookieEnabled -- 返回瀏覽器是否支持(啓用)cookie
9.HTML5 drag api
- dragstart:事件主體是被拖放元素,在開始拖放被拖放元素時觸發,。
- darg:事件主體是被拖放元素,在正在拖放被拖放元素時觸發。
- dragenter:事件主體是目標元素,在被拖放元素進入某元素時觸發。
- dragover:事件主體是目標元素,在被拖放在某元素內移動時觸發。
- dragleave:事件主體是目標元素,在被拖放元素移出目標元素是觸發。
- drop:事件主體是目標元素,在目標元素徹底接受被拖放元素時觸發。
- dragend:事件主體是被拖放元素,在整個拖放操做結束時觸發
10.http2.0
首先補充一下,http和https的區別,相比於http,https是基於ssl加密的http協議 簡要歸納:http2.0是基於1999年發佈的http1.0以後的首次更新。
- 提高訪問速度(能夠對於,請求資源所需時間更少,訪問速度更快,相比http1.0)
- 容許多路複用:多路複用容許同時經過單一的HTTP/2鏈接發送多重請求-響應信息。改善了:在http1.1中,瀏覽器客戶端在同一時間,針對同一域名下的請求有必定數量限制(鏈接數量),超過限制會被阻塞。
- 二進制分幀:HTTP2.0會將全部的傳輸信息分割爲更小的信息或者幀,並對他們進行二進制編碼
- 首部壓縮
- 服務器端推送
11.補充400和40一、403狀態碼
(1)400狀態碼:請求無效
產生緣由:
- 前端提交數據的字段名稱和字段類型與後臺的實體沒有保持一致
- 前端提交到後臺的數據應該是json字符串類型,可是前端沒有將對象JSON.stringify轉化成字符串。
解決方法:
- 對照字段的名稱,保持一致性
- 將obj對象經過JSON.stringify實現序列化
(2)401狀態碼:當前請求須要用戶驗證
(3)403狀態碼:服務器已經獲得請求,可是拒絕執行
12.fetch發送2次請求的緣由
fetch發送post請求的時候,老是發送2次,第一次狀態碼是204,第二次才成功?
緣由很簡單,由於你用fetch的post請求的時候,致使fetch 第一次發送了一個Options請求,詢問服務器是否支持修改的請求頭,若是服務器支持,則在第二次中發送真正的請求。
13.Cookie、sessionStorage、localStorage的區別
共同點:都是保存在瀏覽器端,而且是同源的
-
Cookie:cookie數據始終在同源的http請求中攜帶(即便不須要),即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據還有路徑(path)的概念,能夠限制cookie只屬於某個路徑下,存儲的大小很小隻有4K左右。 (key:能夠在瀏覽器和服務器端來回傳遞,存儲容量小,只有大約4K左右)
-
sessionStorage:僅在當前瀏覽器窗口關閉前有效,天然也就不可能持久保持,localStorage:始終有效,窗口或瀏覽器關閉也一直保存,所以用做持久數據;cookie只在設置的cookie過時時間以前一直有效,即便窗口或瀏覽器關閉。(key:自己就是一個回話過程,關閉瀏覽器後消失,session爲一個回話,當頁面不一樣即便是同一頁面打開兩次,也被視爲同一次回話)
-
localStorage:localStorage 在全部同源窗口中都是共享的;cookie也是在全部同源窗口中都是共享的。(key:同源窗口都會共享,而且不會失效,無論窗口或者瀏覽器關閉與否都會始終生效)
補充說明一下cookie的做用:
-
保存用戶登陸狀態。例如將用戶id存儲於一個cookie內,這樣當用戶下次訪問該頁面時就不須要從新登陸了,如今不少論壇和社區都提供這樣的功能。 cookie還能夠設置過時時間,當超過期間期限後,cookie就會自動消失。所以,系統每每能夠提示用戶保持登陸狀態的時間:常見選項有一個月、三個 月、一年等。
-
跟蹤用戶行爲。例如一個天氣預報網站,可以根據用戶選擇的地區顯示當地的天氣狀況。若是每次都須要選擇所在地是煩瑣的,當利用了 cookie後就會顯得很人性化了,系統可以記住上一次訪問的地區,當下次再打開該頁面時,它就會自動顯示上次用戶所在地區的天氣狀況。由於一切都是在後 臺完成,因此這樣的頁面就像爲某個用戶所定製的同樣,使用起來很是方便
-
定製頁面。若是網站提供了換膚或更換佈局的功能,那麼可使用cookie來記錄用戶的選項,例如:背景色、分辨率等。當用戶下次訪問時,仍然能夠保存上一次訪問的界面風格。
14.web worker
在HTML頁面中,若是在執行腳本時,頁面的狀態是不可相應的,直到腳本執行完成後,頁面才變成可相應。web worker是運行在後臺的js,獨立於其餘腳本,不會影響頁面你的性能。而且經過postMessage將結果回傳到主線程。這樣在進行復雜操做的時候,就不會阻塞主線程了。
如何建立web worker:
- 檢測瀏覽器對於web worker的支持性
- 建立web worker文件(js,回傳函數等)
- 建立web worker對象
15.對HTML語義化標籤的理解
HTML5語義化標籤是指正確的標籤包含了正確的內容,結構良好,便於閱讀,好比nav表示導航條,相似的還有article、header、footer等等標籤。
16.iframe是什麼?有什麼缺點?
定義:iframe元素會建立包含另外一個文檔的內聯框架 提示:能夠將提示文字放在之間,來提示某些不支持iframe的瀏覽器
缺點:
- 會阻塞主頁面的onload事件
- 搜索引擎沒法解讀這種頁面,不利於SEO
- iframe和主頁面共享鏈接池,而瀏覽器對相同區域有限制因此會影響性能。
17.Doctype做用? 嚴格模式與混雜模式如何區分?它們有何意義?
Doctype聲明於文檔最前面,告訴瀏覽器以何種方式來渲染頁面,這裏有兩種模式,嚴格模式和混雜模式。
- 嚴格模式的排版和 JS 運做模式是 以該瀏覽器支持的最高標準運行。
- 混雜模式,向後兼容,模擬老式瀏覽器,防止瀏覽器沒法兼容頁面。
18.Cookie如何防範XSS攻擊
XSS(跨站腳本攻擊)是指攻擊者在返回的HTML中嵌入javascript腳本,爲了減輕這些攻擊,須要在HTTP頭部配上,set-cookie:
- httponly-這個屬性能夠防止XSS,它會禁止javascript腳原本訪問cookie。
- secure - 這個屬性告訴瀏覽器僅在請求爲https的時候發送cookie。
結果應該是這樣的:Set-Cookie=.....
19.Cookie和session的區別
HTTP是一個無狀態協議,所以Cookie的最大的做用就是存儲sessionId用來惟一標識用戶
20. 一句話歸納RESTFUL
就是用URL定位資源,用HTTP描述操做
21.講講viewport和移動端佈局
能夠參考個人這篇文章:
響應式佈局的經常使用解決方案對比(媒體查詢、百分比、rem和vw/vh)
22. click在ios上有300ms延遲,緣由及如何解決?
(1)粗暴型,禁用縮放
<meta name="viewport" content="width=device-width, user-scalable=no">
複製代碼
(2)利用FastClick,其原理是:
檢測到touchend事件後,馬上出發模擬click事件,而且把瀏覽器300毫秒以後真正出發的事件給阻斷掉
4、css篇
1.css盒模型
簡介:就是用來裝頁面上的元素的矩形區域。CSS中的盒子模型包括IE盒子模型和標準的W3C盒子模型。
border-sizing(有3個值哦):border-box,padding-box,content-box.
- 標準盒子模型:
![2018-07-10 4 24 03](http://static.javashuo.com/static/loading.gif)
- IE盒子模型:
![2018-07-10 4 24 12](http://static.javashuo.com/static/loading.gif)
區別:從圖中咱們能夠看出,這兩種盒子模型最主要的區別就是width的包含範圍,在標準的盒子模型中,width指content部分的寬度,在IE盒子模型中,width表示content+padding+border這三個部分的寬度,故這使得在計算整個盒子的寬度時存在着差別:
標準盒子模型的盒子寬度:左右border+左右padding+width IE盒子模型的盒子寬度:width
在CSS3中引入了box-sizing屬性,box-sizing:content-box;表示標準的盒子模型,box-sizing:border-box表示的是IE盒子模型
最後,前面咱們還提到了,box-sizing:padding-box,這個屬性值的寬度包含了左右padding+width
也很好理解性記憶,包含什麼,width就從什麼開始算起。
2.畫一條0.5px的線
-
採用meta viewport的方式
-
採用 border-image的方式
-
採用transform: scale()的方式
3.link標籤和import標籤的區別
- link屬於html標籤,而@import是css提供的
- 頁面被加載時,link會同時被加載,而@import引用的css會等到頁面加載結束後加載。
- link是html標籤,所以沒有兼容性,而@import只有IE5以上才能識別。
- link方式樣式的權重高於@import的。
4.transition和animation的區別
Animation和transition大部分屬性是相同的,他們都是隨時間改變元素的屬性值,他們的主要區別是transition須要觸發一個事件才能改變屬性,而animation不須要觸發任何事件的狀況下才會隨時間改變屬性值,而且transition爲2幀,從from .... to,而animation能夠一幀一幀的。
5.Flex佈局
文章連接: http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool(語法篇) http://www.ruanyifeng.com/blog/2015/07/flex-examples.html(實例篇)
Flex是Flexible Box的縮寫,意爲"彈性佈局",用來爲盒狀模型提供最大的靈活性。 佈局的傳統解決方案,基於盒狀模型,依賴 display屬性 + position屬性 + float屬性。它對於那些特殊佈局很是不方便,好比,垂直居中就不容易實現。
簡單的分爲容器屬性和元素屬性 容器的屬性:
- flex-direction:決定主軸的方向(即子item的排列方法) .box { flex-direction: row | row-reverse | column | column-reverse; }
- flex-wrap:決定換行規則 .box{ flex-wrap: nowrap | wrap | wrap-reverse; }
- flex-flow: .box { flex-flow: || ; }
- justify-content:對其方式,水平主軸對齊方式
- align-items:對齊方式,豎直軸線方向
項目的屬性(元素的屬性):
- order屬性:定義項目的排列順序,順序越小,排列越靠前,默認爲0
- flex-grow屬性:定義項目的放大比例,即便存在空間,也不會放大
- flex-shrink屬性:定義了項目的縮小比例,當空間不足的狀況下會等比例的縮小,若是定義個item的flow-shrink爲0,則爲不縮小
- flex-basis屬性:定義了在分配多餘的空間,項目佔據的空間。
- flex:是flex-grow和flex-shrink、flex-basis的簡寫,默認值爲0 1 auto。
- align-self:容許單個項目與其餘項目不同的對齊方式,能夠覆蓋align-items,默認屬性爲auto,表示繼承父元素的align-items
好比說,用flex實現聖盃佈局
6.BFC(塊級格式化上下文,用於清楚浮動,防止margin重疊等)
直譯成:塊級格式化上下文,是一個獨立的渲染區域,而且有必定的佈局規則。
- BFC區域不會與float box重疊
- BFC是頁面上的一個獨立容器,子元素不會影響到外面
- 計算BFC的高度時,浮動元素也會參與計算
那些元素會生成BFC:
- 根元素
- float不爲none的元素
- position爲fixed和absolute的元素
- display爲inline-block、table-cell、table-caption,flex,inline-flex的元素
- overflow不爲visible的元素
7.垂直居中的方法
(1)margin:auto法
css:
div{
width: 400px;
height: 400px;
position: relative;
border: 1px solid #465468;
}
img{
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
複製代碼
html:
<div>
<img src="mm.jpg">
</div>
複製代碼
定位爲上下左右爲0,margin:0能夠實現脫離文檔流的居中.
(2)margin負值法
.container{
width: 500px;
height: 400px;
border: 2px solid #379;
position: relative;
}
.inner{
width: 480px;
height: 380px;
background-color: #746;
position: absolute;
top: 50%;
left: 50%;
margin-top: -190px; /*height的一半*/
margin-left: -240px; /*width的一半*/
}
複製代碼
補充:其實這裏也能夠將marin-top和margin-left負值替換成, transform:translateX(-50%)和transform:translateY(-50%)
(3)table-cell(未脫離文檔流的)
設置父元素的display:table-cell,而且vertical-align:middle,這樣子元素能夠實現垂直居中。
css:
div{
width: 300px;
height: 300px;
border: 3px solid #555;
display: table-cell;
vertical-align: middle;
text-align: center;
}
img{
vertical-align: middle;
}
複製代碼
(4)利用flex
將父元素設置爲display:flex,而且設置align-items:center;justify-content:center;
css:
.container{
width: 300px;
height: 200px;
border: 3px solid #546461;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
.inner{
border: 3px solid #458761;
padding: 20px;
}
複製代碼
8.關於js動畫和css3動畫的差別性
渲染線程分爲main thread和compositor thread,若是css動畫只改變transform和opacity,這時整個CSS動畫得以在compositor trhead完成(而js動畫則會在main thread執行,而後出發compositor thread進行下一步操做),特別注意的是若是改變transform和opacity是不會layout或者paint的。 區別:
- 功能涵蓋面,js比css大
- 實現/重構難度不一,CSS3比js更加簡單,性能跳優方向固定
- 對幀速表現很差的低版本瀏覽器,css3能夠作到天然降級
- css動畫有自然事件支持
- css3有兼容性問題
9.塊元素和行元素
塊元素:獨佔一行,而且有自動填滿父元素,能夠設置margin和pading以及高度和寬度 行元素:不會獨佔一行,width和height會失效,而且在垂直方向的padding和margin會失 效。
10.多行元素的文本省略號
display: -webkit-box
-webkit-box-orient:vertical
-web-line-clamp:3
overflow:hidden
複製代碼
11.visibility=hidden, opacity=0,display:none
opacity=0,該元素隱藏起來了,但不會改變頁面佈局,而且,若是該元素已經綁定一些事件,如click事件,那麼點擊該區域,也能觸發點擊事件的visibility=hidden,該元素隱藏起來了,但不會改變頁面佈局,可是不會觸發該元素已經綁定的事件display=none,把元素隱藏起來,而且會改變頁面佈局,能夠理解成在頁面中把該元素刪除掉同樣。
12.雙邊距重疊問題(外邊距摺疊)
多個相鄰(兄弟或者父子關係)普通流的塊元素垂直方向marigin會重疊
摺疊的結果爲:
兩個相鄰的外邊距都是正數時,摺疊結果是它們二者之間較大的值。 兩個相鄰的外邊距都是負數時,摺疊結果是二者絕對值的較大值。 兩個外邊距一正一負時,摺疊結果是二者的相加的和。