15

私はjavascriptで静的プロパティをエミュレートしようとしています。class.prototype.propertyは、クラスから継承するすべてのオブジェクトにわたって静的であることがいくつかの場所で言及されています。しかし、私のPOCはそうではないと言います。ご覧ください:

Class.prototype.propertyを使用する

//Employee class
function Employee() {
    this.getCount = function(){
        return this.count; 
    };      
    this.count += 1;
}
Employee.prototype.count = 3;

var emp = [], i;
for (i = 0; i < 3; i++) {
    emp[i] = new Employee();
    console.log("employee count is "+ emp[i].getCount());
}
/*Output is:
employee count is 4
employee count is 4
employee count is 4*/

私の質問#1:これが静的である場合、すべてのオブジェクトが同じカウント変数を共有するため、カウントの値は4、5、6などにすべきではありませんか?

次に、Class.prototypeを使用して別のPOCを実行しましたが、これは静的であると思います。

Class.propertyの使用

//Employee class
function Employee() {
    this.getCount = function(){
        return Employee.count; 
    };      
    Employee.count++;
}
Employee.count = 3;

var emp = [], i;
for (i = 0; i < 3; i++) {
    emp[i] = new Employee();
    console.log("employee count is "+ emp[i].getCount());
}
/*Output is:
employee count is 4
employee count is 5
employee count is 6*/

私の質問#2:class.propertyが直接使用されているのを見たことがありません。上記のコードを念頭に置いて、JavaScriptで静的変数をどの程度正確に作成しますか?

または、ここで何か間違ったコードを作成しましたか?これは正しい認識ではありませんか?

4

1 に答える 1

38

私の質問#1:これが静的である場合、すべてのオブジェクトが同じカウント変数を共有するため、カウントの値は4、5、6などにすべきではありませんか?

プロトタイププロパティはインスタンス間で共有されますが、インスタンスにプロパティの独自のコピーがある場合は、代わりにそれを使用します。インスタンスのプロパティに割り当てると、独自のコピーが提供されるため、プロトタイプは使用されなくなります。

、、、および同様の演算子は割り当てをもたらすため、この動作も引き起こします+=++

検討:

function Employee() {
}
Employee.prototype.count = 0;

上記のコードの時点で、メモリ内に。のオブジェクトがありますEmployee.prototype。いくつかのASCIIアート:

+ ----------- +
| Employee.prototype |
+ ----------- +
| カウント:0 |
+ ----------- +

次に、これを行います。

var e = new Employee();

これで、メモリ内に2番目のオブジェクトがあります。これには次への参照がありますEmployee.prototype

+ ----------- +
| e |
+ -----------
| [[プロトタイプ]]|-----------> | Employee.prototype |
+ -----------
                           | カウント:0 |
                           + ----------- +

そして、あなたが質問した場合e.count

console.log(e.count);

...eという独自のプロパティがないためcount、エンジンはeのプロトタイプを調べてそれを見つけ、それを見つけて、その値を使用します。

ただし、これを行うと:

e.count += 1; // Or more idiomatically, `++e.count;` or `e.count++;`

これにより、インスタンスに値が割り当てられます。現在、独自のコピーがあります:counteecount

+ ----------- +
| e |
+ ----------- +
| カウント:1 | + ----------- +
| [[プロトタイプ]]|-----------> | Employee.prototype |
+ -----------
                           | カウント:0 |
                           + ----------- +

、あなたが質問した場合e.count

console.log(e.count);

...エンジンはを検出counte、プロトタイプを確認しません。

この効果はコードで確認できます。

function Employee() {
}
Employee.prototype.count = 0;

var e = new Employee();
console.log(e.hasOwnProperty('count')); // false
e.count += 1;
console.log(e.hasOwnProperty('count')); // true

console.log(e.count);                   // 1
console.log(Employee.prototype.count);  // 0

これも楽しいです:

var e = new Employee();

console.log(e.count);                   // 0
++Employee.prototype.count;
console.log(e.count);                   // 1

eには(まだ)独自のコピーがないためcount、実際にプロパティをインクリメントすると、直接( )または間接( )Employee.prototypeのどちらで要求しても、更新された値が表示されます。Employee.prototype.counte.count

これに関する最後の注意:eプロパティの独自のコピーを取得した場合は、再度削除できます。

var e = new Employee();
console.log(e.count);    // 0, because it's using `Employee.prototype.count`
++e.count;               // Now `e` has its own `count` property
console.log(e.count);    // 1, `e`'s own `count`
delete e.count;          // Now `e` doesn't have a `count` property anymore
console.log(e.count);    // 0, we're back to using `Employee.prototype.count`

deleteより適切に呼ばれremoveます。オブジェクトからプロパティを削除します。

私の質問#2:class.propertyが直接使用されているのを見たことがありません。上記のコードを念頭に置いて、JavaScriptで静的変数をどの程度正確に作成しますか?

ふたつのやり方:

  1. まさにあなたがそれをしたように、Employee.sharedProperty

  2. 関数内で「クラス」全体を定義し、その関数内でローカル変数を使用することにより、次のようになります。

    var Employee = (function() {
        var sharedVariable = 0;
    
        function Employee() {
            ++sharedVariable;
            console.log("sharedVariable = " + sharedVariable);
        }
    
        return Employee;
    })();
    

    その外部スコープ関数内で定義されたすべての関数は、その中で定義されたローカル変数にアクセスできます。したがって、変数は1つだけです。これは、を作成する外部関数への1回の呼び出し内のローカルEmployeeです。

    次に、このコード:

    new Employee();
    new Employee();
    new Employee();
    new Employee();
    

    出力

    1
    2
    3
    4
于 2012-11-21T04:47:25.743 に答える