0

コンストラクターによって作成された JavaScript オブジェクトのすべてのインスタンスにデータ/関数を追加して、すべてのインスタンスがそのコピーではなく同じ参照を持つようにするにはどうすればよいですか?

基本的に、C# で静的メソッドに相当するものを実装します。

たとえば、Widget クラスを作成する次のコードがあるとします。

(function() {

    var Widget = function() {
    };

    Widget.prototype.init = function(data) {
        this.data = data;
    };

    this.Widget = Widget;
}).call(this);
var instance1 = new Widget();
instance1.init('inst1');
var instance2 = new Widget();
instance2.init('inst2');

alert(instance1.data); // inst1
alert(instance2.data); // inst2

上記の場合、各インスタンスには独自の data プロパティのコピーがあります。ただし、現在および将来のすべてのインスタンスのデータを設定する関数を追加したいと考えています。

私の現在の解決策は、プロトタイプではなく、コンストラクター関数オブジェクトに関数を追加することです。たとえば、以下を参照してください。これには落とし穴があり、より良い方法はありますか?

(function() {

    var Widget = function() {
    };

    Widget.prototype.init = function(data) {
        this.data = data;
    };

    Widget.addStaticData = function(data) {
        this.staticData = data;
    };

    Widget.prototype.getStaticData = function() {
        return Widget.staticData;
    };

    this.Widget = Widget;
}).call(this);
var instance1 = new Widget();
instance1.init('inst1');

Widget.addStaticData('static');

var instance2 = new Widget();
instance2.init('inst2');

alert(instance1.data); // inst1
alert(instance2.data); // inst2
alert(instance1.getStaticData()); // static
alert(instance2.getStaticData()); // static
4

2 に答える 2

2

私が考えることができる3つの落とし穴:

  • 方法論: プロトタイプは共有、再利用、継承された機能/プロパティの場所です - そのまま利用します

  • パフォーマンス: インスタンスで毎回設定するよりも継承する方が高速です。John Resig (jQuery 作成者) は、ブログ投稿でこれに関するベンチマークを行いましたが、現時点では見つけられないようです。

  • 継承されたプロパティと独自のプロパティの間の分割が失われます。コンストラクターを介してすべてをインスタンスに適用すると、すべてがインスタンス プロパティになります。

コンストラクター経由のすべて:

function Dog() { this.legs = 4; }
var fido = new Dog();
fido.name = 'Fido';
for (var i in fido) if (fido.hasOwnProperty(i)) alert(i+' = '+fido[i]);

...インスタンス自身のものと見なされるため、両方のプロパティを警告します。

プロトタイプとコンストラクター経由

function Dog2() { }
Dog2.prototype.legs = 4;
var fido = new Dog2();
fido.name = 'Fido';
for (var i in fido) if (fido.hasOwnProperty(i)) alert(i+' = '+fido[i]);

name...それが唯一のインスタンス プロパティであるという理由だけで警告します。(それにもかかわらず、fido.legs取得可能ですが、プロトタイプからのものです)。

[編集 - 以下の OP のコメントに応じて]

静的メソッドが必要な場合は、宣言の後に関数に追加する必要があります。

function Dog() {}
Dog.static = function() {}
于 2012-08-01T13:50:28.333 に答える
1

プロパティstaticDataの代わりにローカル変数を検討してください。Widget.staticDataそうすれば、外部コマンドはデータを直接書き込むことができないため、データを書き込む唯一の方法はaddStaticData関数を使用することになります。

(function () {
    var Widget = function () {};
    var staticData;

    Widget.addStaticData = function ( obj ) {
        staticData = obj.data;
    };

    Widget.prototype.init = function () {
        var data = staticData;
        // use data
        // or just use the staticData variable directly
    };

    this.Widget = Widget;
}).call( this );

あなたのコードでは、これを実行するだけです:

Widget.staticData = { data: 'COMPROMISED!' };

静的データを変更します。静的データを設定するための専用関数があるため、他の方法で静的データを変更できるようにしたくない場合があります。

私のコードでは、上記のステートメントは効果がなく、静的データはaddStaticData関数を介してのみ変更できます。

于 2012-08-01T14:04:24.013 に答える