97
54

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 3 years have passed since last update.

【Vue】一体いつから括弧無しメソッドと括弧有りメソッドが同じだと錯覚していた?

Last updated at Posted at 2020-07-23

Vueでメソッドの末尾に()をつけた時とつけない時の挙動の違い

以前からVueを使っていて疑問だったことがありました。

それはVueのmethodsで定義したメソッド(関数)をテンプレートで使うとき、
末尾に()をつけたメソッドと()のないメソッドの両方を使用可能であるという事実です。

具体的にどういうことかコードで説明してみます。

下のコードでmethodという名のメソッドがVueのmethodsプロパティで定義されているとします。

このときtemplate内から呼び出すときは、method()methodの両方が使えてしまいます。
(ちなみに<script></script>タグ内では括弧無しの呼び出しmethodは呼び出しになりません)

<template>
  <!-- どちらの書き方でも正常に実行される -->
  <div>
    <div id="example1">
      <!-- メソッド名(括弧無し)をv-onに渡した場合 -->
      <button @click="method">括弧無し</button>
    </div>

    <div id="example2">
      <!-- メソッド名(括弧有り)をv-onに渡した場合 -->
      <button @click="method()">括弧有り</button>
    </div>
  </div>
</template>

はじめは、括弧なし呼び出しは括弧あり呼び出しの省略形ぐらいに考えていたのですが、調べてみたところ大きな違いがありました。

Vue詳しい方にとっては当たり前なのかもしれませんが、備忘録として残しておくことに。

調べてわかったこと

結論から書くと、次のような違いがあるということでした。

括弧あり呼び出し

  • 引数無しの場合は引数は何も取らずに(当然ですが)、メソッドが呼び出されるだけ
  • 引数がある場合も定義にしたがってメソッドが呼び出される

特に問題なく、普通のJSの関数(メソッド)と同じ挙動だと思います。

括弧なし呼び出し

  • 引数として**Eventオブジェクトが暗黙に渡され、**メソッドが実行される

一見、引数が何も無いので、単に引数無しのメソッドが呼び出されているように見えますが、実はそのDOMで発生したEventオブジェクトが引数にわたっています。

例を交えて

以下参考にしたページです。

次の例では比較のためにブラウザのアラートを出す3種のボタンを用意してます。

VueのJS側では、対応するVueインスタンスのmethodsプロパティにsay()というメソッドを用意しています。say()メソッドは引数を1つ受け取るように定義されています。また、内部では受け取ったEventオブジェクトのタイプをJSのalert()で表示する処理が書かれています。

See the Pen PoZLwYb by Masa U. (@masa_u1128) on CodePen.

まず、「括弧有り」ボタンをクリックすると、「TypeError: Cannot read property 'type' of undefined」とアラート表示されます。引数を渡していないのでエラーが出るのは当然でしょう。

次に、「括弧無し」ボタンをクリックすると、「Eventオブジェクトのタイプはclickです」とアラート表示されます。

何...だと...?

繰り返しになりますが、引数は渡していません。これは引数に暗黙的にEventオブジェクトが渡されているためです。

最後に「括弧有り(引数に$eventを渡している)」ボタンを押してみましょう。この場合は引数に$eventという変数を渡してメソッド呼び出しをしています。結果は「括弧無し」ボタンと同じになります。ちなみに頭に$のついた変数はVueであらかじめ用意された特殊な変数で、$eventはDOMイベントオブジェクトを格納する変数として使われます。

おそらく、括弧無し呼び出しのときは$eventが暗黙的に引数として渡されているということだと思います。

まとめ

以上のことから、括弧無し呼び出しでは暗黙的に引数にEventオブジェクトが渡されてることが分かりました。

普通に使っている分には括弧有りと無しのどちらを使っても問題ないような気がしますが、括弧無しの場合は1つ注意したいケースがあります。

それはデフォルト引数を使っている場合です。デフォルト引数があると、暗黙的に渡されるEventオブジェクトが引数となってしまうので、期待する結果と異なる結果が得られてしまいます。この場合は括弧有りの呼び出しを使うべきでしょう。

個人的には括弧をつけた方がぱっと見でメソッドであることが分かりやすく、算出プロパティと区別しやすいのでEventオブジェクトを使わない場合は括弧有り呼び出しを使った方がいいのかなと思っています。

(それにしても、公式ドキュメントを読んでもさらっと数行で済ましているので違いを理解するのに時間が少しかかった:sweat_smile:

97
54
2

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
97
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?