0

昨日、プロトタイプの継承とコンストラクタについて投稿しました。私は最終的に、コードをきれいに整頓し、プロトタイプをそのままにしておくアプローチに落ち着きましたが、パフォーマンスへの影響はわずかでした。

function Card(value) {
    // setValue is a public instance method
    this.setValue = function (val) {
        if (!range[val]) {
            val = drawRandom();
        }

        // value is a public instance variable
        this.value = val;

        return val;
    };

    this.setValue(value);
}

ただし、このアプローチの問題は、検証を取得するために Card インスタンスの値を設定するたびに setValue メソッドを呼び出さなければならないことです。代わりにやりたいことは、カスタム セッター メソッドを用意することです。これが私がこれまでに持っているものです:

function Card(val) {
    // value is a private instance variable
    var value;

    // This is a private instance method
    // It's also self-invoking, but that's beside the point
    (function (x) {
        if (!range[x]) {
            x = drawRandom();
        }

        value = x;
    }(val));

    this.__defineGetter__("value", function () {
        return value;
    });

    // Some code duplication
    this.__defineSetter__("value", function (x) {
        if (!range[x]) {
            return false;
        }

        value = x;

        return x;
    });
}

これはうまくいきます。呼び出すvar card = new Card()とランダムな値を持つインスタンスが返さcard.value = nullれますが、範囲外であるため呼び出しは失敗します。

これに関する私の問題は、明らかにはるかに長いという事実以外に、コードの一部を複製しているように見えることです。セッターメソッドがコンストラクターと一緒に呼び出されるといいでしょう。そうすれば、自己呼び出しプライベート インスタンス メソッド全体を排除できます。

4

2 に答える 2

2

関数は Javascript のファースト クラス オブジェクトであるため、次のようなことを行うだけで重複を排除できます。

function setter (x) {
    if (!range[x]) {
        return false;
    }
    return x;
}
(function (x) {
    value = setter(x);
    if (!value) {
        value = drawRandom();
    }

}(val));

this.__defineGetter__("value", function () {
    return value;
});

// Some code duplication
this.__defineSetter__("value", setter);
于 2012-07-26T19:55:21.297 に答える
1

まず、検証を呼び出すため、内部であってもvaluewithを常に設定する必要があります。obj.value = newValueコンストラクター内では、次のことを意味します。

this.value = val;

ただし、セッターとゲッターが宣言される前にそれを行うと、うまくいきません。そのため、設定時にセッター関数が存在するように、後で移動します。


ここでの実例: http://jsfiddle.net/8tCjm/4/

var drawRandom = function () {
    return Math.floor(Math.random() * 3) + 1;
};

var range = {
    1: 'Ace',
    2: 'Two',
    3: 'Three'
};

function Card(val) {
    var value;

    this.__defineGetter__('value', function () {
        return value;
    });

    this.__defineSetter__('value', function (x) {
        if (range[x]) {
            value = x;
        } else {
            value = drawRandom();
        }

        return value;
    });

    this.value = val;
};

console.log(new Card(1).value); // 1
console.log(new Card(2).value); // 2
console.log(new Card(3).value); // 3

console.log(new Card(987).value); // not 987 (1-3)
​
于 2012-07-26T19:55:06.590 に答える