2017-02-19 25 views
1

關於SO的第一個問題,我希望我不會重複任何內容;我已經看過otherquestions,並認爲我不同意足以保證提問。有沒有一種方法在使用ES6速記方法符號的方法中使用`this`這個詞彙?

基本上,有沒有辦法讓this在使用簡寫符號寫成的方法的方法體中是詞法還是綁定到特定值?

這樣做的動機來自我想在實施iterator protocol時使用ES6方法的速記,其中@@iterator方法在調用時返回一個迭代器對象。該迭代器對象必須有一個next()方法,該方法在調用時會返回另一個對象。在第二個對象中,我想引用原始的(在我的例子中爲Graph)實例。

注意,在下面的代碼片段,它不工作按計劃到期this結合,next()使用ES6 method definition shorthand來。

class Graph { 
    constructor(initialNodes) { 
    this.data = [...initialNodes]; 
    } 

    [Symbol.iterator]() { 
    let nextIndex = 0; 
    // `this` binding is fine here, as expected 
    return { 
     // look at that beautiful shorthand 
     next() { 
     return nextIndex < this.data.length 
      // `this` binding is not fine here 
      ? { done: false, value: this.data[nextIndex++] } 
      : { done: true }; 
     } 
    }; 
    } 
} 

我知道定義函數的對象返回到上面,然後指定爲被返回的對象的屬性,功能,但同樣我在想,如果用該方法語法速記的方式是可能的。

返回的對象上述定義next()作爲常規函數然後在對象屬性賦值結合它:

class Graph { 
    // constructor 

    [Symbol.iterator]() { 
    let nextIndex = 0; 
    // I know you can do this 
    const next = function() { 
     return nextIndex < this.data.length 
     ? { done: false, value: this.data[nextIndex++] } 
     : { done: true }; 
    }; 
    return { 
     next: next.bind(this) 
    }; 
    } 
} 

定義next()返回的對象爲箭頭函數上述裝置不需要bind,但仍然沒有一種方法語法速記:

class Graph { 
    // constructor 

    [Symbol.iterator]() { 
    let nextIndex = 0; 
    // I know you can also do this 
    const next =() => { 
     return nextIndex < this.data.length 
     ? { done: false, value: this.data[nextIndex++] } 
     : { done: true }; 
    }; 
    return { 
     next 
    }; 
    } 
} 

Icepickle帶到了評論好點,我可以只使用存儲this上下文中d是指速記方法體中的那個。我認爲這是我能得到的最接近的?

class Graph { 
    // constructor 

    [Symbol.iterator]() { 
    let nextIndex = 0; 
    const self = this; 
    return { 
     next() { 
     return nextIndex < self.data.length 
      ? { done: false, value: self.data[nextIndex++] } 
      : { done: true }; 
     } 
    }; 
    } 
} 
+0

'下:()=>'並不比'下長得多()'。我只想跟那個一起去。 – Ryan

+3

箭頭語法的要點在於,它繼承了詞彙'this',而不是從它被稱爲的'this'。人們似乎只想現在只使用箭頭語法,並以某種方式使其完成原始語法所做的一切。這不僅僅是它的設計。如果你不打算使用詞法'this',那麼你可能不應該使用箭頭語法。使用更長的語法,然後你可以'.bind()'到你的心中。 – jfriend00

+0

@ jfriend00:他們要求相反的,我認爲:詞彙'this',但仍然用簡寫法表示。 – Ryan

回答

1

您的問題,理想的解決方案是使用這項工作的合適的工具:一個generator function。它們也可以與shorthand syntax一起使用,並且它們將正確綁定this

生成器函數返回符合iterator protocol的對象,並且可以使用yield*將迭代器的輸出委託給另一個可迭代對象(如數組)。

class Graph { 
 
    constructor(initialNodes) { 
 
    this.data = [...initialNodes]; 
 
    } 
 

 
    * [Symbol.iterator]() { 
 
    yield* this.data; 
 
    } 
 
} 
 

 
const graph = new Graph([1, 2, 3]); 
 
for (const node of graph) { 
 
    console.log(node); 
 
}

+0

哇,謝謝!我沒有考慮過發電機,因爲我沒有完全培養他們,但我想他們不是很難理解。這很酷,尤其是速記。我注意到在MDN速記生成器方法鏈接中,'*'和生成器的名稱之間有一個空格,而在你的代碼片段中沒有。我查了一下airbnb的風格指南,看看他們的想法,並且看到他們甚至不推薦使用迭代器或者生成器。對此有何想法? https://github.com/airbnb/javascript#iterators-and-generators – abigsmall

+0

@abigsmall他們不喜歡迭代器的原因是因爲他們鼓勵使用非函數式語法。如果你創建了一些小的幫助函數,你可以使用生成器。我個人發現生成器語法超級強大,並且轉換爲數組就像'[... graph]'一樣簡單。我不知道速記符號有一個標準樣式,謝謝! – 4castle

+0

感謝您的回答,@ 4castle :) – abigsmall

相關問題