[Javascript] 関数宣言の落とし穴 function foo ( ){..} と var foo = function ( ) {..} は動作が違うので要注意!
function funcname(args){ do something}; は var funcname = function(args){ do something}; と等価になる。javascriptを理解するためのたった2つの大切なこと
javascriptを理解するためのたった2つの大切なこと:改
引用元の記事はすばらしい記事ですが、ここは間違いです。
等価だと思っていたらひどい目にあいます。
サイ本 第5版
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