前端面試:基礎javascript篇(一)
(1)get請求傳參長度的誤區
誤區:我們經常說get請求引數的大小存在限制,而post請求的引數大小是無限制的。
實際上HTTP 協議從未規定 GET/POST 的請求長度限制是多少。對get請求引數的限制是來源與瀏覽器或web伺服器,瀏覽器或web伺服器限制了url的長度。為了明確這個概念,我們必須再次強調下面幾點:
HTTP 協議未規定 GET 和POST的長度限制
GET的最大長度顯示是因為瀏覽器和 web伺服器限制了 URI的長度
不同的瀏覽器和WEB伺服器,限制的最大長度不一樣
要支援IE,則最大長度為2083byte,若只支援Chrome,則最大長度 8182byte
(2)補充get和post請求在快取方面的區別
1:get請求和post請求的區別
https://www.cnblogs.com/logsharing/p/8448446.html
GET和POST本質上就是TCP連結,並無差別。但是由於HTTP的規定和瀏覽器/伺服器的限制,導致他們在應用過程中體現出一些不同。GET和POST還有一個重大區別,簡單的說:GET產生一個TCP資料包;POST產生兩個TCP資料包。對於GET方式的請求,瀏覽器會把http header和data一併傳送出去,伺服器響應200(返回資料);而對於POST,瀏覽器先發送header,伺服器響應100 continue
get請求類似於查詢的過程,使用者獲取資料,可以不用每次都與資料庫連線,所以可以使用快取。
post不同,post做的一般是修改和刪除的工作,所以必須與資料庫互動,所以不能使用快取。因此get請求適合於請求快取。
閉包
閉包就是能夠讀取其他函式內部變數的函式,或者子函式在外呼叫,子函式所在的父函式的作用域不會被釋放。
(5)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