前端面試-基礎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請求在快取方面的區別
post/get的請求區別,具體不再贅述。
補充補充一個get和post在快取方面的區別:
- get請求類似於查詢的過程,使用者獲取資料,可以不用每次都與資料庫連線,所以可以使用快取。
- post不同,post做的一般是修改和刪除的工作,所以必須與資料庫互動,所以不能使用快取。因此get請求適合於請求快取。
3. 閉包
一句話可以概括:閉包就是能夠讀取其他函式內部變數的函式,或者子函式在外呼叫,子函式所在的父函式的作用域不會被釋放。
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)來實現
連結:https://juejin.im/post/5b44a485e51d4519945fb6b7