Javascript,衝鴨系列——前端刷面經
2018-10-30
1、淺拷貝和深拷貝的區別,實現。
區別:
淺拷貝:只拷貝指向物件的指標;
深拷貝:拷貝一個物件的值,重新生成一個物件
實現:
淺拷貝:直接賦值
深拷貝:
function deepCopy(obj){ if(!(obj instanceof Object)) return; var res; if(obj instanceof Array) res = []; else res = {}; for(key in obj){ if(!(obj[key] instanceof Object)) res[key] = obj[key]; else res[key] = deepCopy(obj[key]); } return res; }
2、ES6中的箭頭函式。
作用:
- 與變數解構結合使用
- 使表達更加簡潔
- 簡化回撥函式
注意點:
- 函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件。
- 不可以當作建構函式,即不可以使用new命令,否則會丟擲錯誤。
- 不可以使用arguments物件,該物件在函式體內不存在。如果要用,可以用rest引數代替。
- 不可以使用yield命令,因此箭頭函式不能用作Generator函式。
3、理解閉包。
推薦一篇部落格:前端基礎進階(四):詳細圖解作用域鏈與閉包
閉包更確切的說是一項技術或者一個特性,函式作用域中的變數在函式執行完成只有就會被垃圾回收。正常情況下無法訪問函式作用域中的變數,而通過閉包可以實現,即通過在函式作用域中建立內部函式,使得函式執行完成後變數不會被回收。
應用場景:
- 柯里化
- 模組化
演算法題:
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大小為0,請返回0。
function minNumberInRotateArray(rotateArray)
{
// write code here
if(rotateArray.length===0) return 0;
if(Array.from(new Set(rotateArray)).length === 1) return rotateArray[0];
for(let i=0; i<rotateArray.length-1; i++){
if(rotateArray[i]>rotateArray[i+1]){
return rotateArray[i+1];
}
}
}
2018-10-31
4、理解this。
this的指向,是在函式被呼叫的時候確定的,也就是執行上下文(execution context)被建立時確定的。
在一個函式上下文中,this由呼叫者提供,由呼叫函式的方式來決定。如果呼叫者函式,被某一個物件所擁有,那麼該函式在呼叫時,內部的this指向該物件。如果函式獨立呼叫,那麼該函式內部的this,則指向undefined。但是在非嚴格模式中,當this指向undefined時,它會被自動指向全域性物件。匿名函式的this物件通常指向window。
推薦一篇博文:前端基礎進階(五):全方位解讀this
5、實現一個bind函式。
定義:bind()是ES5中定義的函式的方法。
作用:建立一個函式的例項,其this值會被繫結到傳給bind()函式的值。
典型例子:
var color = 'red'; var o = { color : 'blue' } function getColor(){ return this.color; } getColor(); // "red" var newGetColor = getColor.bind(o); newGetColor(); // "blue"
藉助閉包和apply方法,封裝一個bind方法。
function bind(fn, o){ return function(){ return fn.apply(o, arguments); } }
6、通過new操作符呼叫建構函式的實際過程。
- 建立一個新的物件
- 將建構函式的this指向這個新物件
- 為這個物件新增屬性,方法等
- 返回新物件
7、對於作用域鏈的理解。
作用域鏈是指向變數物件的指標列表,每個變數物件關聯著一個執行上下文,識別符號的解析沿著作用域鏈從下到上層級搜尋,保證對執行上下文有權訪問的變數和函式的有序訪問。
2018-11-1
8、在給事件繫結回撥函式的時候,event和e的區別是什麼。
IE和Chrome中的事件物件是作為全域性物件(window.event)存在的,Firefox中則是作為控制代碼(handler)的第一個引數傳入內的。
所以常見獲取事件的方法是:
// Dom0級事件處理 ele.onEventName = handler; // Dom2級事件處理 // 與上者實現相同的效果 // 第三個引數預設為false,冒泡階段呼叫handler ele.addEventListener('eventName', handler, false); function handler(e){ var evt = window.event || e; //等價形式如下 //var evt = window.event || arguments[0]; }
9、函式防抖是什麼,怎麼實現。
詳見筆者博文:JavaScript,衝鴨系列——函式防抖
2018-11-2
10、事件迴圈(event loop)機制。
JavaScript是單執行緒的,這個執行緒擁有唯一的一個事件迴圈,但是可以擁有多個非同步任務佇列,任務佇列用來存放相應的回撥函式或者事件處理方法。如下圖任務佇列分為:macro和micro兩種,不同源型別的任務進入不同的任務佇列。
事件迴圈的順序決定了程式碼的執行順序。從script開始,按照macro——micro的順序交替執行,且無論是什麼型別的任務,都需要借用函式呼叫棧來完成。