前端面試ES6系列:箭頭函式和普通函式的區別

okfine17發表於2019-04-20

基本用法

箭頭函式

let sum = (a, b) => {
    return a + b;
}
複製程式碼

普通函式

var sum = function (a, b){
    return a + b;
}
複製程式碼

區別

之前看阮一峰前輩 es6 文章裡提過這個知識點,但是昨天面試被問到了,只回答出了this,所以趕緊抽空整理下知識點,查缺補漏,下面開始正文。

1、 this指向問題

這一點要特別注意,也是面試的時候面試官最關注的。 箭頭函式的this指向的是父級作用域的this,是通過查詢作用域鏈來確定 this 的值也就是說,看的是上下文的this,指向的是定義它的物件,而不是使用時所在的物件;普通函式指向的是它的直接呼叫者。

(1)普通函式的 this 指向可以參考阮一峰的js的this用法 當聽到你說 this 的問題,面試官可能會接下去問你 this 的一些擴充問題了,如何改變 this 指向,比如bind方法什麼的,然後還可能讓你實現 bind,總之真的很多可以問的。
(2)箭頭函式的this

let obj = {
        a: 1,
        b: () => {
            console.log(this.a); // undefined
        },
        c: function() {
            console.log(this.a); // 1 
        },
    };
obj.b();
obj.c();
複製程式碼

箭頭函式沒有this,它的this是繼承來的,預設指向定義它的時候的物件,就是我們說的宿主物件,而不是執行它的物件。這裡通過obj.b(),此時this指向的window物件,上面沒有a,所以返回undefined。通過obj.c(),this指向的是它的直接呼叫者,就是obj,所以返回1。

var obj = {
        a:1, 
        print(){
            setTimeout(
               function(){console.log(this.a);},
               1000
           );
        }
    };
obj.print();//undefined
複製程式碼

定時器中的函式由於沒有預設宿主物件,setTimeout中的function未被任何物件呼叫,它的this指向預設是window物件,自然輸出undefined。

var obj = {
        a:1,
        print(){
            setTimeout(
               () => { console.log(this.a); },
               1000
            );
        }
    };
    obj.print();// 1
複製程式碼

箭頭函式的this指的是定義它的物件,所以this指向的是obj物件,所以obj.a確實應該輸出1。 ⚠️最後注意,我們前文一直都強調箭頭函式沒有 this,所以呢,我們不可以用 call()、apply()、bind() 這些方法去改變this的指向。

2、不可以被當作建構函式

不能被當作建構函式來使用,通過new命令來作為建構函式會報錯,這裡沒有構建原型的說法,不存在prototype這個屬性,也不能通過super訪問原型的屬性,而且new target也是不能用的。

3、不可以使用arguments物件,該物件在函式體內不存在,如果要用就用rest引數替代。

function f1(arr) {
        console.log(arguments);
    }
f1([1,2,3]); // [1,2,3]
    
let f2 = (arr) => {
    console.log(arguments);
}
f2([1,3,9]); //Uncaught ReferenceError: arguments is not defined

let f3 = (...arr) => {
  console.log(arr);
}
f3([1,4,5]); // [1,4,5]
複製程式碼

4、不可以使用yield命令,因此箭頭函式不能用作 Generator 函式。

後記

最近因為準備面試,所以打算整理下知識點,方便進行知識整理鞏固,文中如有不正確的地方,煩請溫柔的批評指正~

相關文章