2

最後に、次のコードに閉鎖の匂いがします。

function create(parent) {
var F = function() {};
 F.prototype = parent;
return new F();
}

var masterObject = {a: "masterObject value"}
var object1 = create(masterObject);
var object2 = create(masterObject);
var object3 = create(masterObject);
var object3.a = "overridden value";

object1.a; // "masterObject value"
object2.a; // "masterObject value"
object3.a; // "overridden value"

masterObject.a = "new masterObject value"//value is changed now

object1.a; // "new masterObject value"
object2.a; // "new masterObject value"
object3.a; // "overridden value"

object1.a 、abject2.a の値は永久に変更されます。これは、グローバル変数を変更したためですか、それとも閉鎖の影響ですか?Create()関数を再度呼び出していないため、値が自動的に変更されるのはなぜですか? 最後の質問「グローバル変数を変更すると、tht 変数を使用するすべてのオブジェクトに自動的に影響しますか?」その変数を有効にするには、Create() 関数を再度呼び出す必要がありますね。

4

3 に答える 3

3

にアクセスするobject3.aと、JavaScript は最初にオブジェクトのプロパティを調べます。オブジェクトに というプロパティがない場合はa、次にオブジェクトのプロトタイプがチェックされます。

設定object3.a = "overridden value";によりobject3、 と呼ばれるプロパティが得られますaaプロトタイプのプロパティには影響しません。

object1object2には というプロパティがありませんが、aそのプロトタイプにはあるため、 のプロパティを変更するとmasterObject、プロトタイプとしてa持つすべてのオブジェクトの値がグローバルに変更されますmasterObject

object3というプロパティを指定しましたが、プロトタイプのプロパティにaアクセスすることはできますが、これは同じままです。a

object3.__proto__.a; // "new masterObject value"

基本的に、object3というプロパティを与えるaことで、オブジェクトの新しいプロパティをプロトタイプのプロパティの「前」に置きます。

于 2013-01-06T10:31:31.640 に答える
0

これは、javascript などのプロトタイプベースの言語で継承がどのように機能するかによって発生します。を呼び出すと、プロトタイプが に設定されcreate(masterObject)た関数オブジェクト ( を呼び出す) の新しいインスタンスが返されます。これは、 、、およびのプロトタイプ フィールドが同じオブジェクト を指していることを意味します。FmasterObjectobject1object2object3masterObject

ステートメント:

object3.a  = "overriden value"

ainというフィールドを作成し、object3それに文字列を割り当て"overriden value"ますobject3.a。しかし、 を見ると、インタープリターはフィールドが に存在しないobject1.aことに気づき、その親へのプロトタイプ リンクをたどり、 というフィールドを調べます。この場合、プロトタイプ リンクは、文字列を保持するというフィールドを指しており、それが表示されます。というフィールドがなかった場合、インタプリタは、フィールドが見つかるまで、またはプロトタイプ リンクが空のオブジェクトに到達するまで、プロトタイプ リンクを何度もたどり、値を返します。aobject1amasterObjecta"masterObject value"masterObjectaaundefined

したがって、 を変更すると、 とmasterObject.aを調べたときに表示される内容が変わります。と には というフィールドがないため、親である からそれを「継承」します。object1.aobject2.aobject1object2amasterObject

これは、文字列を保持するinというobject3.aフィールドを作成したため、調べたときに発生しません。aobject3"overridden value"

コードの最後に次を追加するとします。

delete object3.a;

というフィールドがなくなったため、親から「継承」されているため、"new masterObject value"を見るとわかります。object3.aobject3amasterObject

于 2013-01-06T10:49:48.517 に答える
0

オブジェクトの 'a' プロパティを直接変更するとvar object3.a = "overridden value";(前に a があってはならないvar)、そのインスタンス自体の 'a' プロパティが変更されます。

したがって、実際に何が起こるかは次のとおりです。

object3.a = "overridden value";ここでは、object3 に新しいプロパティを作成します。以前は「a」プロパティがありませんでした。ただし、そのプロトタイプはobject3.a有効であり、プロトタイプの 'a' プロパティを参照します。

masterObject.a = "new masterObject value"ここで、すべてのオブジェクトのプロトタイプcreate()を変更します (によって作成されます)。したがって、オブジェクトのプロパティ 'a' にアクセスすると、独自の 'a' プロパティ (object3 など) を除いて変更されます。

于 2013-01-06T10:34:47.540 に答える