1

私は以下の状況を思いついた:

function Dog () {
    "use strict";
    this.age = 1;
    var name = "Fido";
    this.getName = function () { return name; }
}

そして今、私は「Dog」クラスの新しいインスタンスを作成し、変数の値を出力しています。

var d = new Dog;
document.write('<strong>Dog age:</strong> ' +d.age); \\Outputs "1" as expected
document.write('<br/>');
document.write('<strong>Dog name:</strong> ' +d.name); \\Outputs "undefined" as expected, 'cause it's a private variable.
document.write('<br/>');
document.write('<strong>Get Dog name:</strong> ' +d.getName()); \\Outputs "Fido", as expected.

しかし、次のように犬の名前を変更したいとします。

d.name = "Stinky";
document.write('<br/>');
document.write('<strong>Dog name Again:</strong> ' +d.name); 
document.write('<br/>');
document.write('<strong>Get Dog name Again:</strong> ' +d.getName());

これに基づいて、私はいくつかの質問を受けました:

  1. いったいなぜ「d.name」は私に「undefined」を表示しなかったのですか?「名前」はプライベート変数ではありませんか?プライベート変数の値は変更できないと思いますよね?このプロセスで新しい変数が作成されたのではないかと思いますが、今回はパブリック変数で、同じ名前です。もしそうなら、同じ名前の新しいプロパティを割り当てようとするたびに新しい変数が作成されないようにする方法はありますか?「タイプエラー」などをスローする方法はありますか(まあ、これは私が期待していたことでした)。
  2. そして最後に:新しい値を割り当てた後でも、なぜ「getName」は元の値「Fido」を出力したのですか?

何か案は?

これが物事を簡単にするためのfidです。

http://fiddle.jshell.net/yZpfg/2/

4

3 に答える 3

6

d.name = "Stinky";dオブジェクトに新しい(パブリック)プロパティを追加しています。これはinstanceOf Dog。です。

ゲッターは引き続き(プライベート)変数を値で参照しますFido

コンシューマーがプライベート変数を変更できるようにする場合は、セッターも必要です。

function Dog () {
    "use strict";
    this.age = 1;
    var name = "Fido";
    this.getName = function () { return name; }
    this.setName = function (value) { name = value; }
}

var d = new Dog(); 
d.name; // undefined because there is no name public property
d.getName() // returns the internal private, "Fido"
d.setName('Stinky'); // the internal private is now "Stinky"
于 2012-07-24T17:51:19.253 に答える
1

ローカル変数とインスタンスプロパティを混同しています。これらは完全に別個のものです。

1)d.nameインスタンスプロパティを設定します。これは、プライベート変数ではなく、呼び出しているものです。

2)Fidoはプライベート変数の値であり、インスタンスプロパティではなく、メソッドが返すものであるため、メソッドは常にFidoと表示します。

元のコードはおそらく次のようになります。

function Dog () {
    "use strict";
    this.age = 1;
    this.name = "Fido";
}
Dog.prototype.getName = function() { return this.name; }

メソッドを各インスタンスに明示的に追加するのではなく、プロトタイプに追加することに注意してください。このようにして、インスタンスはそれを継承します。これはより良い方法です。再利用可能なコードはプロトタイプ上にある必要があり、すべてのインスタンスに毎回追加するよりもパフォーマンスが優れています。

于 2012-07-24T17:53:03.740 に答える
1

var nameコンストラクター内someObj.nameで、同じものになることは決してありません。2つの異なるものに設定できる2つの異なる値。代わりに、ゲッターのように機能するセッター関数が必要です。

this.setName = function(newName) { name = newName; };

プライベート変数と同じ名前のプロパティを設定するときにエラーを発生させる方法はありません。これらは2つのまったく異なるものであり、インターセプトすることさえできるプロパティが設定されている場合、コールバックはありません。

于 2012-07-24T17:53:40.090 に答える