JavaScriptを学んでいますが、理解できないことがたくさんあります。
は、次のJavaScriptコードのログは何をコンソールになります:1問のオンラインのJavaScriptクイズでは、次の質問が現れJavaScript:関数実行命令
const a = {};
const b =() => a.a =() => {};
const c = c => '' + c + a.a(b());
const d = console.log.bind(console);
const e = (e =>() => d(c(e++)))(0);
try{
e();
}catch(a){
e();
}
これは、各変数(ここでは定数)の略かを理解するために私にいくつかの時間がかかりました。 ブロック内のe()
のコードの解析を開始しました。したがって、e
はクロージャを表します。つまり、関数d
が引数c(0)
で呼び出され、e
が1
になります。私が理解したように、d
は基本的にconsole.log
関数を表しています(しかし、なぜ彼らはbind
を使用しましたか?)
今のところ私は最初にc(0)
が実行され、コンソールに結果が記録されることを知っていますか?関数c
を見てみましょう。最初の引数を文字列に変換し、連結結果をa.a(b())
に返します。さて、a.a(b())
が最初に実行されるでしょう、そうですか?しかし、問題はa.a
が関数ではないため、定義されていないため、エラーがスローされ、catch
に行きます。
今、catch
ブロックではすべてが同じである必要があります。したがって、a.a
はまだ関数ではなく、参照エラーがスローされるはずです。しかし、それはエラーがスローされていないことを見たとき私は驚いたが、コンソールは実際に1undefined
を記録する。どうして?どうやって?
私は少し考えた後、おそらくa.a(b())
をb()
と呼び出すと、最初に実行されることに気づきました。私の想定に従えば、オブジェクトa
のオブジェクトa
のプロパティに何もしない関数への参照b
の参照を右に?しかし、a.a
は関数であり、try
ブロックで実行され、0undefined
がログに記録されます。
しかし、これらの2つの仮定は正しいものではありません。ここでの主な質問は最初に実行されるものです。 someObject.propertyWhichIsNotAFunction(somethingWhichMakesItAFunction)
とすると、どうなりますか?最初に実行されるのは何ですか? try
ブロック1つがまず実行され、catch
他のものであるようです。それは本当に私にとって意味をなさない。説明は?
これは、 'a.a'が関数でない場合、引数を評価する際に何が起こっても、参照エラーをスローする必要があることを意味します(評価自体がエラーをスローする場合を除く)。まあ、それはかなり変だ。私はJavaScriptが 'f1()'や 'f2()'のような不必要な計算を避けるように設計されていると考えました。私たちが呼ぶことができないことを確かに知っている関数参照の引数を評価するロジックは何ですか? –
@ manga171引数に 'b()'のような副作用があります。 specは最適化以上の正しさに焦点を当てており、 'isReady()&& go()'は 'go() 'を呼び出さないことが保証されているなど、' f1()&& f2() 'if' isReady() 'false' false'を返すと、関数を呼び出す前に関数の引数を評価しないことによるメリットはありません。反対の質問はもっと面白いです:引数を評価する前に関数参照を評価するロジックは何ですか? – Paulpro
@ manga171その答えはおそらく、仕様が完璧ではなく、既存のコードに影響を与える変更を行うことは大したことです。 'let argListはどうするの? ArgumentListEvaluation(Arguments).'が常に発生するので、任意の条件から取り除き、関数が評価されたときに最初に実行することは可能ですが、問題のコードの動作は変更されます例外を投げることはありません。私は '0undefined'を出力すると思います。 – Paulpro