8

オブジェクトリテラルを使用して、メソッドを使用してオブジェクトを作成していました。
ここに簡単な例があります。

var SizeManager = {
    width : 800,
    height : 600,
    ratio : this.width / this.height,
    resize : function (newWidth) {
        width = newWidth;
        height = newWidth / ratio;
    }
}

私の問題は、SizeManager.ratioが「NaN」を返すことです。初期化の問題だと確信しています。
正しい比率値を取得する方法はありますか?
コストラクタまたはイニシャライザをオブジェクトリテラルに割り当てる方法はありますか?
コンストラクターオブジェクトを定義することが唯一の方法ですか?

編集:もちろん、SizeManagerは理想的にはシングルトン(1つのオブジェクトのみ)です。これは、オブジェクトリテラルを使用していた方法です。

4

3 に答える 3

24

はい、初期化の問題です。オブジェクトを使用している時点でオブジェクトをthis参照していません。SizeManager(オブジェクト初期化子は の値を変更しませんthis。)thisは、関数の呼び出し方法によって設定され、その関数呼び出し全体で同じ値を持ちます。そこでは関数を呼び出していないためthis、そのコードの開始前に持っていた値は何でもあります。

(これの最後にある特定の例から何かを指摘しましたratioが、最初に、あなたが提起した一般的なケースのいくつかのオプションを見てみましょう。)

ダニエルratioは、幅を変えたいと思っていることに気付いていないように見えることを除いて、関数を作成する上であなたに良い操縦を与えました. または、widthheightが変わらない場合は、後で計算します。

var SizeManager = {
    width : 800,
    height : 600,
    resize : function (newWidth) {
        this.width = newWidth;
        this.height = newWidth / this.ratio;
    }
};
SizeManager.ratio = SizeManager.width / SizeManager.height;

(補足: でthis.参照しているプロパティに追加しましたresize。元のものにはありませんでしたが、必須です。それらがないと、暗黙のグローバルの恐怖に対処することになり、これは悪いことです( tm) .)

もちろん、そのすべてをファクトリにカプセル化することもできます。

function makeSizeManager(width, height) {
    return {
        width : width,
        height : height,
        ratio : width / height,
        resize : function (newWidth) {
            this.width = newWidth;
            this.height = newWidth / this.ratio;
        }
    };
}
var SizeManager = makeSizeManager(800, 600);

resize...しかし、それを実際のコンストラクター関数にすることもできるので、多くの重複する (ただし同一の)関数を作成しないでください。

function SizeManager(width, height) {
    this.width = width;
    this.height = height;
    this.ratio = width / height;
}
SizeManager.prototype.resize = function (newWidth) {
    this.width = newWidth;
    this.height = newWidth / this.ratio;
};
var aSizeManagerInstance = new SizeManager(800, 600);

(この最後の名前を少し変更したことに注意してください。)

最後の最後の注意として、あなたの特定の例では、実際にはratioまったく保存する必要はありません。これを行うことができます:

var SizeManager = {
    width : 800,
    height : 600,
    resize : function (newWidth) {
        var ratio = this.width / this.height;
        this.width = newWidth;
        this.height = newWidth / ratio;
    }
};

しかし、それはその特定の例のためだけであるため、上記の議論は一般的なケースについて話している.

于 2010-09-22T14:23:57.340 に答える
5

ratioおよびへの変更に基づいてプロパティを変更する場合、プロパティは実際にはメソッドである必要がありwidthますheight

var SizeManager = {
    width : 800,
    height : 600,
    ratio : function() {
      return this.width / this.height;
    },
    resize : function (newWidth) {
        width = newWidth;
        height = newWidth / ratio;
    }
}

また、メソッド内でandの代わりにthis.widthandを参照することもできます。this.heightwidthheightresize

于 2010-09-22T14:23:02.337 に答える
0

オブジェクト リテラルthisでは、関数内にある場合にのみオブジェクト リテラル自体を参照します。オブジェクトリテラルの代わりに、このようなものを試すことができます。this関数の内側と外側の両方で作成しているオブジェクトを参照します。

var SizeManager = new function(){
    this.width = 800;
    this.height = 600;
    this.ratio = this.width / this.height;
    this.resize = function (newWidth) {
        this.width = newWidth;
        this.height = newWidth / this.ratio;
    }
}

これは、シングルトン パターンで機能します。複数の SizeManager が必要な場合は、オブジェクトではなくコンストラクター関数にします。

function SizeManager (w, h){
  w && (this.width=w);
  h && (this.height=h);
  this.ratio = this.width / this.height;
}
SizeManager.prototype={ 
  width: 800,
  height: 600,
  resize: function (newWidth) {
    this.width = newWidth;
    this.height = newWidth / this.ratio;
  }
}
于 2010-09-22T14:28:20.520 に答える