[Javascript] 関数宣言の落とし穴 function foo ( ){..} と var foo = function ( ) {..} は動作が違うので要注意!

| カテゴリ:
function funcname(args){ do something};

は

var funcname = function(args){ do something};

と等価になる。
javascriptを理解するためのたった2つの大切なこと
javascriptを理解するためのたった2つの大切なこと:改

引用元の記事はすばらしい記事ですが、ここは間違いです。
等価だと思っていたらひどい目にあいます。
サイ本 第5版のp.96にちゃんと書いてあります。
function文はプログラムの静的な構造を定義するだけなのです。
JavaScriptコードが解析されコンパイルされたときに、関数は定義されます。

どういうことかというと、
function foo( ){ ... }
コンパイル時に関数が定義されます。

var foo = function( ){ ... };
代入文の実行時に関数が定義されます。

その証拠に、
foo();
function foo(){ alert(1) }
はOKですが、

foo(); // エラー
var foo = function (){ alert(1) };
はエラーになります。

ささいな違いに見えますが、プロトタイプを使うときは要注意です。
プロトタイプを使ったメソッド定義は必ず代入文だからです。

メソッド定義は代入文!!

FireFoxでは下記のようなメソッド定義をしようとすると、何故かエラーになります。(IEでは動きます)
function Foo(){  }; // クラス宣言
function Foo.prototype.greet(){ alert('hi') }; // エラー
従って、メソッド定義は代入文で書くことになります。
function Foo(){  }; // クラス宣言
Foo.prototype.greet = function (){ alert('hi') }; // メソッド定義は代入文で

正常に動作するケース

よって、下記のコードは動きます。
function Foo(){  };
Foo.prototype.greet = function (){ alert('hi') };

var foo = new Foo();
foo.greet();

これも動きます。
Foo.prototype.greet = function (){ alert('hi') };
function Foo(){  };

var foo = new Foo();
foo.greet();

こんなのもOKです。
Foo.prototype.greet = function (){ alert('hi') };

var foo = new Foo();
foo.greet();

function Foo(){  };

こんなんだって動いちゃいます。
var foo = new Foo();

Foo.prototype.greet = function (){ alert('hi') };

foo.greet();

function Foo(){  };

エラーになるケース

これはエラーです。
var foo = new Foo();
foo.greet();

function Foo(){  };
Foo.prototype.greet = function (){ alert('hi') };

これもエラーです。
var foo = new Foo();
foo.greet();

Foo.prototype.greet = function (){ alert('hi') };
function Foo(){  };
おわかりでしょうか?

まとめ

  • function foo ( ){..} と var foo = function ( ) {..} は、関数が生成されるタイミングが違う
  • プロトタイプによるメソッドの宣言は、代入文である。
  • メソッドの代入は、
     クラス宣言をした後、かつ、インスタンスからメソッド呼び出しをする前
    にやるべし。

トラックバック(0)

トラックバックURL: http://dqn.sakusakutto.jp/mt/mt-tb.cgi/253

コメント(1)

筆者です。
訂正ありがとうございます。
その辺については説明すると記事が冗長になる気がして書かなかったのですが、完全なシンタックスシュガーだとおもってかくと問題が発生する場合もありますね。

コメントする

人気記事

このブログ記事について

ひとつ前の記事:「[JavaScript] 猿でもわかるクロージャ超入門 まとめ

次の記事:「デュアルモニター環境を構築したらめちゃめちゃ快適になりました。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

最近の人気記事