1. 程式人生 > >ES6系列之箭頭函數

ES6系列之箭頭函數

tro 動態 可能 指向 ren dde 綁定 module bsp

本系列是在平時閱讀、學習、實際項目中有關於es6中的新特性、用發的簡單總結,目的是記錄以備日後溫習;本系列預計包含let/const、箭頭函數、解構、常用新增方法、Symbol、Set&Map、Proxy、reflect、Class、Module、Iterator、Promise、Generator、async/await。。。

箭頭函數顧名思義就是帶箭頭的函數,^-^,其實想表達的是箭頭函數本質還是函數,那箭頭函數和es5的函數有什麽區別呢?

  • 不綁定this
    var obj = {
            age: 1,
            say: function() {
                setTimeout(
    function() { console.log(this, this.age); // window undefined }, 0); }, } var obj1 = { age: 1, say: function() { setTimeout(() => { console.log(this, this.age); // obj1 1 }, 0); } };

    這裏可以看出箭頭函數中訪問的this實際上是其父級作用域中的this,箭頭函數本身的this是不存在的,這樣就相當於箭頭函數的this是在聲明的時候就確定了(因為相當於作用域嘛),這個特性是很有用的

    var handler = {
            id: ‘111‘,
            doSomething: function(e) {
                console.log(e);
            },
            init: function() {
                document.addEventListener(‘click‘, (event) => { //
    這裏綁定事件,函數this就可以訪問到handler的方法doSomething this.doSomething(event); }, false); } } handler.init();
  • 不可以作為構造函數來使用
    var Person = (name) => { // Uncaught TypeError: Person is not a constructor
            this.name = name;
        }
    
        var person = new Person(‘Jack‘);

    這個特性很容易測試,如果上一條明白的話也很容易理解: 箭頭函數壓根就沒有this,當然不能作為構造函數(如果明白構造函數new的過程的話,插一句: new的過程其實就是創建一個對象,將this指向該對象,然後執行代碼初始化這個對象,最後返回)

  • 不綁定arguments(如果有要使用arguments的時候可以使用rest參數代替)
    var foo = (val) => {
            console.log(arguments); // Uncaught ReferenceError: arguments is not defined
        };
        foo();

    這個特性也很好測試,但是實在要使用arguments對象要怎麽辦呢?我們可以使用es6的另一個新特性rest參數,完美替代

    var foo = (...args) => {
            console.log(args); // [1, 2, 3]
        };
        foo(1, 2, 3);
  • 不可以使用yield命令,因此箭頭函數不能用作Generator函數(這個後面總結到generator函數時再做解釋)

箭頭函數不適用的場景(或者不建議使用的場景)

這裏說的不適用有些是壓根不能用,有些是如果使用了箭頭函數可能會產生意想不到的結果

  1. 作為對象的屬性
    var obj = {
            a: () => {
                console.log(this); // window
            }
        };

    作為對象的屬性時,this的指向則不再是對象本身了,這就造成了意想不到的結果

  2. 構造函數(前文已經說過)
  3. 作為原型方法
    function Person(name) {
            this.name = name;
        }
    
        Person.prototype.say = function() {
            console.log(this); // 指向實例
        };
    
        Person.prototype.bark = () => {
            console.log(this); // window
        };
    
    
        var pe = new Person(‘Jack‘);
        pe.say(); // {name: ‘Jack‘}
        pe.bark(); // window

    從例子中我們看到了,箭頭函數作為原型方法時,this指向出乎了我們的意料

  4. 需要動態this的時候(這個地方需要自己進行判斷),這裏只舉個例子便於理解
    document.addEventListener(‘click‘, () => {
            console.log(this); // window
        }, false);
    
        document.addEventListener(‘click‘, function() {
            console.log(this); // #document對象
        }, false);
    
    // 一般情況,我們綁定事件處理函數時希望函數內部的this指向綁定的Dom對象,但是如果使用了箭頭函數,則this則會出乎我們的意料

ES6系列之箭頭函數