LoginSignup
10
4

More than 3 years have passed since last update.

あら、こんなところに副作用

Last updated at Posted at 2019-12-03

JavaScriptを書いていると、意外なところで副作用を発生させることができてしまいます。

プロパティ参照

たとえば、こんなコードを考えてみます。

const foo = new Foo();
foo.bar;

ここでの2行目は無意味な文にも見えますが、Fooの中身によってはこれが副作用を持つことがありえます。

class Foo{
  get bar(){
    alert('副作用');
  }
}

ということで、プロパティ参照はその見た目によらず、他のコードを実行可能、ということになります。

文字列展開

これは比較的わかりやすいかもしれませんが、文字列変換に際してはオブジェクトのtoStringメソッドが呼び出されます。

const obj = {
  toString() {
    alert('副作用');
    return '文字列';
  }
}

`${obj}`; // 文字列を定義しただけでアラートされる

Proxyオブジェクト

ES6で追加されたProxyオブジェクト(MDN)は、意外なところにもフックを仕込めて、副作用を発生させられます。

  • in演算子によるプロパティチェック
  • delete演算子によるプロパティ削除
  • Object.***による各種のオブジェクト操作

実運用に与える影響

もちろん、「toString()が余計な副作用を持つオブジェクト」なんてものは使いづらいので、実用することはないかと思います。とはいえ、考慮しないといけない場面はありえます。

  • DOMプロパティの中には、参照するだけで再描画を行うものがありますので、あえて使うにしろ、うっかり使って余計な再描画が入ってしまうパターンにしろ要注意です。
  • コードのminifyを行う際も、「元のコードの動作を変えられない」というのは大前提になりますので、obj.propertyWithVeryLongNameのようなものが大量にあっても、1つにまとめることはありません。自分で変数に受けるなどしたほうがいい場面もあるかもしれません。
10
4
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
10
4