1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

D3のコードをES5からES6に書き直す場合はthisの扱いに注意

Posted at

はじめに

ES5書かれていたd3のコードをES6に書き直した際に、文法的には間違っていないのにエラーが発生したのでメモ。

問題

selectAll()で取得した要素をeach()でループ処理する際に、各要素を適切に取得できていなかった。

エラー箇所

修正後

d3.selectAll('.hoge')
  .each(d => {
    const fuga = d3.select(this); // DOM内にhogeクラスはあるのに変数fugaがundefinedてしまう
    fuga.append('piyo')
    ...
  })

修正前

d3.selectAll('.hoge')
  .each(function(d) {
    const fuga = d3.select(this); // DOM内にhogeクラスはあるのに変数fugaがundefinedてしまう
    fuga.append('piyo')
    ...
  })

エラー内容

d3 select this createElementNS' of undefined"

select()で要素が適切に取得できていないため、DOM操作に失敗していた。

原因

アロー関数内のthisはスコープが従来と異なるため

詳細は以下の記事に詳しく書いてありました。
[アロー関数はthisの値を語彙的に束縛する”らしい] (https://qiita.com/mejileben/items/69e5facdb60781927929#%E3%82%A2%E3%83%AD%E3%83%BC%E9%96%A2%E6%95%B0%E3%81%AFthis%E3%81%AE%E5%80%A4%E3%82%92%E8%AA%9E%E5%BD%99%E7%9A%84%E3%81%AB%E6%9D%9F%E7%B8%9B%E3%81%99%E3%82%8B%E3%82%89%E3%81%97%E3%81%84) @ Qiita

対策

  1. 従来のES5の文法でfunctionを定義
  2. d3で用意されている引数を利用

2のやりかた

d3.selectAll('.hoge')
  .each((d, i, nodes) => {
    const fuga = d3.select(nodes[i]);
    fuga.append('piyo')
    ...
  })

おわりに

ES5の関数定義 = ES6のアロー関数定義 とひとくくりに考えていたためハマってしまった。よくよく考えると、文と式の違いだからスコープが違うのは当たり前か。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?