1. 程式人生 > >Javascript,衝鴨系列——前端刷面經

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中的箭頭函式。

作用:

  1. 與變數解構結合使用
  2. 使表達更加簡潔
  3. 簡化回撥函式

注意點:

  1. 函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件。
  2. 不可以當作建構函式,即不可以使用new命令,否則會丟擲錯誤。
  3. 不可以使用arguments物件,該物件在函式體內不存在。如果要用,可以用rest引數代替。
  4. 不可以使用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操作符呼叫建構函式的實際過程。

  1. 建立一個新的物件
  2. 將建構函式的this指向這個新物件
  3. 為這個物件新增屬性,方法等
  4. 返回新物件

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的順序交替執行,且無論是什麼型別的任務,都需要借用函式呼叫棧來完成。