2016-04-25 8 views
1

すべてのJSの専門家に Stoyan Stefanov(オブジェクト指向のJS)からの書籍を使用してJSをまだ学ぼうとしています。JS - 自分自身を書き換える関数の混乱

は本が提案

a = a(); // First Call 
 
function a() { 
 
alert('A'); 
 
a = function() { // I get this. Redefining functions. 
 
    alert('B'); 
 
}; 
 
} 
 
a(); // Second Call

、以下のコードが動作しなければならないページ83、上で立ち往生我々はコール/ 2回目のために呼び出す場合ことがあろうとアラートAが発生した後、実際にアラートB

しかし、それは私たちにはTypeErrorを与える代わりに取り組んで:機能は成功し、アラートA.ここでいただきまし間違い

後ではありません?

はあなたが

答えて

2

最初の行ありがとう:

a = a(); 

は、関数を呼び出し、aにその戻り値を割り当てます。しかし、関数の戻り値はundefinedです。returnで明示的に値を返さない関数は暗黙的にundefinedを返します(newで呼び出されない限り、ここでは無視できます)。だから最後の行でa()と言ったら、基本的にはundefined()と言っています。もちろん、undefinedは機能ではありません。

本のコードは実際にa = a();と言っていましたか?それをa()に変更すると、期待どおりに動作します。

またあなたは、むしろ直接aを上書きするよりも最初の呼び出しで新しい関数を返すために機能を変更することができます:

a = a(); // First Call 
function a() { 
alert('A'); 
// following line changed to return the new function instead 
// of assigning it to a immediately 
return function() { 
    alert('B'); 
}; 
} 
a(); // Second Call 
+0

ので、正しいものではなく、その 'return関数(){警告( 'B')}'でなければなりません。それで、本からの間違い? – xcode

+0

はい、 'a = a()'で動くような関数を返します。私はそれを私の答えに加えます。 – nnnnnn

+0

ありがとうございます。非常に明確で有用な答え – xcode

0

あなたが最初の呼び出し

a = a(); // First Call 

を行うと、あなたがする関数の結果を割り当てますあなたの変数a。しかしあなたのa()は何も返しません。したがって、2回目の試行では、aはundefinedです。

最初の行をちょうどa()に変更すると修正されます。

0

この例は、JavaScriptで変数と関数の名前とスコープの重要性を示しています。次のコードを考えてみましょう...

a = a(); 
console.log('typeof global variable a :',(typeof a)); 
function a() { 
    console.log('A'); 
    a = function() { 
     console.log('B'); 
    }; 
    console.log('typeof global function a() inner function a() :',(typeof a)); 
} 
console.log('typeof global function a() :',(typeof a)); 
a(); 

//=> ! TypeError: a is not a function 
//=> A 
//=> typeof global function a() inner function a() : function 
//=> typeof global variable a : undefined 
//=> typeof global function a() : undefined 

何が起こっているのですか?

function a()の内部変数aはその型を返します。function

グローバル変数afunction a()の戻り値に設定されている - しかし、それは自動的にundefined

になるように関数が何も返しませんグローバルfunction a()のタイプは、依然としてそれ自体の「外」の値aによって決定されます(つまり、話す) - undefined

N console.log()への呼び出しが到着する順序を確認しますか?

内部はvarで設定されていないだけでなく、自動的にグローバルスコープ内に配置されますが、a = a()はもはや機能ではありません。

a = a()で、a is not a function TypeErrorが発生します。一方

、私はa =を除去するが、それはあったように他のすべてを残したときに何が起こるか見て...

a(); 
console.log('typeof global variable a :',(typeof a)); 
function a() { 
    console.log('A'); 
    a = function() { 
     console.log('B'); 
    }; 
    console.log('typeof global function a() inner function a() :',(typeof a)); 
} 
console.log('typeof global function a() :',(typeof a)); 
a(); 

//=> A 
//=> typeof global function a() inner function a() : function 
//=> typeof global function a() : function 
//=> typeof global variable a : function 
//=> B 

は、順序がどのように変化したかを参照してください?

変数として 'グローバル変数a'(これまでと同じ)を考えることはできません。aは関数を指すトークンに過ぎません。呼び出され

function a()は、console.log()を発射新しい関数に(それ自体である)トークンaをリセットし、再度呼び出さconsole.log( B )を放ちます。

このようにして、より詳細な結果が得られますが、コンソールへの呼び出しは何が起こっているのかを示す大きな手がかりになります。この例を使用可能なパターンとは考えてはいけません.JavaScriptエンジンがどのように動作するかについてヒントを与えるものと考えてください。

あなたはJavaScriptIsSexy.com便利からこの記事を見つけるかもしれない:JavaScript Variable Scope and Hoisting Explained

+0

あなたの助けをありがとう。あなたが使用可能なパターンについて言及する方法では、あなたはjavascriptアプリケーションの最新のパターンを学ぶために推薦する良い本? – xcode

関連する問題