web-dev-qa-db-ja.com

なぜvar x = x = x || {} var x = x ||より詳細{}?

初心者としてきれいなJavascriptコードを書きたいと思って、最近この段落を見つけたときにJavaScriptの名前空間について この記事 を読んでいた:

次のサンプルの一番上にあるコードは、変数(オブジェクトの名前空間)を定義する前に既に存在するかどうかを確認するさまざまな方法を示しています。通常、開発者はオプション1を使用しますが、オプション3と5はより徹底的であり、オプション4はベストプラクティスと見なされます。

_// This doesn't check for existence of 'myApplication' in
// the global namespace. Bad practice as you can easily
// clobber an existing variable/namespace with the same name
var myApplication = {};

/*
The following options *do* check for variable/namespace existence.
If already defined, we use that instance, otherwise we assign a new
object literal to myApplication.

Option 1: var myApplication = myApplication || {};
Option 2  if(!MyApplication) MyApplication = {};
Option 3: var myApplication = myApplication = myApplication || {}
Option 4: myApplication || (myApplication = {});
Option 5: var myApplication = myApplication === undefined ? {} : myApplication;

*/
_

オプション1は、私がほとんどの時間で使用しているのを見たことは確かであり、よく理解しています。

オプション2は問題ありませんが、事前に_var myApplication_がないか、myApplicationでない場合はif(!window.myApplication)がないようです。グローバルスコープでは、条件if(!myApplication)がエラーをスローしませんか?

オプション3は私が悩んでいるものです:私の理解では、_myApplication = myApplication_が最初に実行され、myApplicationがグローバルスコープ(先頭のvarによる)。私の問題は、このオプションがオプション1以外のことをするケースを考えられないことです。

私の目のオプション4は、myApplicationがグローバルにない場合にエラーをスローしないように、window.myApplication || (myApplication = {})と書いた方が良いでしょう範囲。

オプション5undefined以外のfalse-y値を除外していますが、それは良い考えですか? myApplicationが空の文字列である場合、残りのコードは失敗する可能性がありますよね?

誰かが異なるオプションの違いにいくらかの光を当てることができ、特にオプション3がより徹底的に記述されている理由を説明できますか?

35
Jacques Gaudin

記事がオプション3が「より徹底的」であると主張している場合、それは間違っています。その割り当てチェーンの中間にはまったく意味がありません。

誰かが異なるオプションの違いにいくらかの光を当てることができ、特にオプション3がより徹底的に記述されている理由を説明できますか?

まず、警告:2018年には、おそらくこれらのいずれも使用したくないでしょう。代わりに、さまざまなモジュール定義構文( [〜#〜] amd [〜#〜]CommonJSRequireJS )、関連ツール、または import および export (そしておそらく Babel などの関連ツールと Webpack または Browserify 。ただし、Chrome、Safari、およびEdgeの現在のバージョンはモジュールをネイティブにサポートしますが、Firefoxは現在もフラグをサポートしています)。

なぜ_var x = x = x || {}_は_var x = x || {}_よりも完全なのですか?

そうではありません。

オプション2は問題ありませんが、事前に_var myApplication_がないか、myApplicationでない場合はif(!window.myApplication)がないようです。グローバルスコープでは、条件if(!myApplication)がエラーをスローしませんか?

はい。 (生産がグローバルスコープで発生すると仮定します。グローバルスコープではなく、現在のスコープチェーン内にスコープ内にmyApplicationがある場合、myApplicationは未解決のシンボル。)

オプション3は私が悩んでいるものです:私の理解では、_myApplication = myApplication_が最初に実行され、myApplicationがグローバルスコープ(先頭のvarによる)。私の問題は、このオプションがオプション1以外のことをするケースを考えられないことです。

いいえ、持っている場合

_var myApplication = myApplication = myApplication || {}
_

これは物事が起こる順序です:

  1. _var myApplication_は、グローバルが存在しない場合は作成し、存在する場合はそのままにします
  2. _myApplication || {}_が評価され、myApplication(真実の場合)または_{}_(そうでない場合)の値を取ります。それを_value1_と呼びましょう
  3. _myApplication = value1_(中央のもの)が実行され、結果は_value1_になります
  4. _myApplication = value1_(左側のもの)は、正当な理由なしに再度実行されます

私の目のオプション4は、myApplicationがグローバルにない場合にエラーをスローしないように、window.myApplication || (myApplication = {})と書いた方が良いでしょう範囲。

確かに。

オプション5undefined以外のfalse-y値を除外していますが、それは良い考えですか? myApplicationが空の文字列である場合、残りのコードは失敗する可能性がありますよね?

はい。

54
T.J. Crowder