[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 ( ) {..} は、関数が生成されるタイミングが違う
- プロトタイプによるメソッドの宣言は、代入文である。
- メソッドの代入は、
クラス宣言をした後、かつ、インスタンスからメソッド呼び出しをする前
にやるべし。
カテゴリ:
JavaScript