0

Addy Osmani からJavascript Design Patternsを読んでいます。ドキュメントでは、この単純な割り当てを使用して、 「既存のオブジェクト/名前空間の上書きを防ぎます」 :

var myNS = myNS || function() {};

したがって、変数が既に存在する場合は同じオブジェクトを変数に割り当て、(理想的には) 存在しない場合は空のオブジェクトを作成することを理解しています。したがって、このオブジェクトのプロトタイプにメソッドを追加するとしますが、既存の同様の名前のオブジェクトには、'Hi!' を出力する同様の名前のメソッドが既にありました。次のことが起こるはずですよね?

myNS.prototype.sayHello = function() { return 'Hello!' }; 
myNS.sayHello(); // Hello! ??

そしてオリジナルmyNS.sayHello() // Hi!はまだ上書きされていますよね?つまり、この場合の条件付き変数の割り当ては、1 レベルの名前衝突回避を追加することを除いて、何をしますか? それとも私はこれについて完全に間違っていますか?

4

2 に答える 2

1

この形式の割り当ての目的は、名前の競合を回避することではなく、既存のオブジェクトを保持することです。

たとえば、オブジェクトにプロパティまたはメソッドを追加する 2 つのコードがあり、どちらが最初に実行されるかわからない場合、またはそれを制御できない場合は、両方に次のような代入を使用させることができます。

var myNS = myNS || {};
myNS.doSomething = function(){ ... };

そして他の場所:

var myNS = myNS || {};
myNS.doSomethingElse = function() { ... };

両方のコードが実行されると、両方のメソッドを持つオブジェクトが作成され、どちらのコードも、特定の順序で存在したり実行したりするために他のコードに依存しません。


新しいオブジェクトが必要な場合は、単純に新しいオブジェクトを作成する必要があります。

命名の競合のみを回避したい場合は、コードを関数スコープ内に保持して、すべての変数がそのスコープに対してローカルになり、グローバル スコープから同じ名前の変数をシャドウするようにする必要があります。このアプローチは、他のライブラリに干渉する可能性のあるグローバル スコープをできるだけ小さくするために、多くのライブラリで使用されています。

于 2014-06-19T19:10:11.530 に答える
1

sayHelloに関数を追加するスクリプトと、 に関数を追加myNSする別のスクリプトを用意することが考えられます。sayGoodbyemyNS

var myNS = myNS || {};これらの各スクリプトでパターンを使用すると、次のことが可能になります。

  • 存在しないオブジェクトへの書き込みを試みることなく、スクリプトの 1 つをロードする
  • 2 番目のスクリプトが最初のスクリプトを破壊することなく、どちらの順序でも両方のスクリプトをロードします。

オブジェクトの同じメソッドを上書きする 2 つのスクリプトに対する保護は提供されません。

于 2014-06-19T18:58:36.100 に答える