1

オブジェクトのインスタンスが作成されるたびに変更できる動的な値として、プロトタイプでオブジェクトプロパティを定義する方法があるかどうかを調べようとしています。それは私がそれを説明できる最良の方法の一種です。私は自分がやろうとしていることを示すためにフィドルを作成しました(それは機能しませんが)。

var Response = {
    LCID: 321
};


Date.prototype.LCID = Number(0);
Date.prototype.LCID.valueOf = function() { return Response.LCID; };


document.write((new Date()).LCID);
Response.LCID = 456;
document.write((new Date()).LCID);

http://jsfiddle.net/tx2fW/2/

私が達成しようとしているResponse.LCIDのは、後でコード内の値を変更することからわかるように、コードの存続期間中に変更される可能性があるということです。Dateオブジェクトを作成するときは常に、の値を、最初に作成したときの値だけでなく(new Date()).LCID、の現在の値にします。Response.LCIDDate.prototype.LCID

これを行う方法はありますか?最大の制限は、JavaScript 1.5で動作する必要があることです...ただし、最近のバージョンで動作するかどうかを知りたいと思います。

4

3 に答える 3

1

Number(0) === 0. プリミティブ値を変更.valueOfしても効果はありません。.toString

これを行う正しい方法は、 operatorを使用してコンストラクターのインスタンスを渡すことです。Numbernew

var Response = {
    LCID: 321
};
Date.prototype.LCID = new Number();   // <-- Use the "new" operator
Date.prototype.LCID.valueOf = function() { return Response.LCID; };

注釈付きのデモとメモ: http://jsfiddle.net/tx2fW/7/

  • LCIDはオブジェクトです。typeof new Date().LCID === 'object'.
  • LCIDの真のインスタンスですNumbernew Date().LCID instanceof Number === true
  • LCIDは 321 に等しい:(new Date().LCID == 321) === true
  • LCIDは 321: と同一ではありません(new Date().LCID === 321) === false
    (LCID はオブジェクトであり、321 は基本的な数値であるため)。

PS。vs に慣れていない場合は、どの等号演算子 (== vs ===) を JavaScript 比較で使用する必要がありますか? を==参照===してください。

于 2012-04-15T10:10:19.960 に答える
1

これは__defineGetter__メソッドを使用して行われますが、すべてのブラウザでどのように動作するかはわかりませんが、あなたが望むものを達成するために見つけることができる唯一の方法です(今回はそれがあなたが望むものだと思います)

http://jsfiddle.net/tx2fW/6/実例。

var Response = {
    LCID: 321
};

var d = Date.prototype;

d._LCID = Number(0);
d.getLCID = function() {
    if (d._LCID != Response.LCID) d._LCID = Response.LCID;
    return d._LCID ;
};
d.__defineGetter__("LCID", function() {
    return this.getLCID();
});

document.write((new Date()).LCID);
Response.LCID = 456;
document.write((new Date()).LCID);​

別の方法については、この投稿__defineGetter__を参照してください

于 2012-04-15T08:46:06.347 に答える
0

さらに調査と実験を行った結果、実際に問題を解決することができました。私はDateコンストラクターなどで遊んでみましたが、最初の試行ではあまり運がありませんでした-どうやら、Dateオブジェクトが呼び出される方法によって機能が異なるという点でユニークであるという事実を見落としていたためです(関数またはオブジェクトコンストラクター)。これは、返されるのは文字列だけであるため、単に実行できないことを意味しますDate.prototype.constructor.apply(this, arguments)(Dateオブジェクトは関数として呼び出されています)。

このスレッドを見つけて読んだ後、実際のDateオブジェクト(または関数として呼び出された場合は文字列)を作成し、組み込みのDateオブジェクトを完全に模倣する次のコードを思いつきました(テストで示されている限り)。新しいDateオブジェクトが作成されるたびに、オブジェクトの作成中に動的に生成されるLCIDプロパティが取得されます。これは、まさに私が必要としていたものです。

Date = (function(orig) {
    var date = function(a, b, c, d, e, f, g) {
        var object = (this instanceof Object ? (arguments.length < 1 ? new orig() : (arguments.length < 2 ? new orig(a) : (arguments.length < 4 ? new orig(a, b || 0, c || 1) : new orig(a, b, c, d || 0, e || 0, f || 0, g || 0)))) : orig());
        object.LCID = Response.LCID;

        return object;
    };
    date.prototype = orig.prototype;

    return date;
})(Date);

また、組み込みのDateオブジェクト、またはこのコードを使用して違いがないことを確認するために、一連のテストケースを作成しました(組み込みのDateオブジェクトを使用して結果を確認し、比較するには、このコードをコメント化してください)。

var Response = { 'LCID': 123 };


Date = (function(orig) {
    var date = function(a, b, c, d, e, f, g) {
        var object = (this instanceof Object ? (arguments.length < 1 ? new orig() : (arguments.length < 2 ? new orig(a) : (arguments.length < 4 ? new orig(a, b || 0, c || 1) : new orig(a, b, c, d || 0, e || 0, f || 0, g || 0)))) : orig());
        object.LCID = Response.LCID;
        return object;
    };
    date.prototype = orig.prototype;
    return date;
})(Date);


var x = new Date();
document.writeln(x);
document.writeln(x.LCID);
document.writeln(x.getFullYear());
document.writeln(typeof x);
document.writeln(Object.prototype.toString.call(x));
document.writeln(x instanceof Date);
document.writeln("<br/>");

Response.LCID = 456;

var y = new Date();
document.writeln(y);
document.writeln(y.LCID);
document.writeln(y.getFullYear());
document.writeln(typeof y);
document.writeln(Object.prototype.toString.call(y));
document.writeln(y instanceof Date);
document.writeln("<br/>");

document.writeln(Date());
document.writeln(new Date());
document.writeln(new Date(2012));
document.writeln(new Date(2012, 7));
document.writeln(new Date(2012, 7, 14));
document.writeln(new Date(2012, 7, 14, 9));
document.writeln(new Date(2012, 7, 14, 9, 45));
document.writeln(new Date(2012, 7, 14, 9, 45, 27));
document.writeln(new Date(2012, 7, 14, 9, 45, 27, 687));

これは、更新されたフィドルとしても利用できます:http: //jsfiddle.net/tx2fW/9/

于 2012-04-17T00:55:51.333 に答える