11

標準の Date オブジェクトの動作を変更したいと思います。0..99コンストラクターに渡される年の間はfullYear(no add of 1900) として解釈する必要があります。しかし、私の次の機能は機能しません

var oDateConst = Date.prototype.constructor; // save old contructor

Date.prototype.constructor = function () {
    var d = oDateConst.apply(oDateConst, arguments); // create object with it
    if ( ((arguments.length == 3) || (arguments.length == 6))
        && ((arguments[0] < 100) && (arguments[0] >= 0))) {
        d.setFullYear(arguments[0]);
    }
    return d;
}

なぜ呼び出されないのですか?この問題をどのように解決しますか?

4

4 に答える 4

34

呼び出されない理由は、 のconstructorプロパティを変更しているためですDate.prototype。ただし、コードを使用して日付を作成している可能性がありますnew Date()。したがって、コンストラクターは使用されません。本当にやりたいことは、独自の Date コンストラクターを作成することです。

function MyDate() {
    var d = Date.apply(Date, arguments);
    if ((arguments.length == 3 || arguments.length == 6)
        && (arguments[0] < 100 && arguments[0] >= 0)) {
        d.setFullYear(arguments[0]);
    return d;
}

次に、次のように新しい日付を作成できます。

var d = MyDate();

編集:使用する代わりに、コンストラクター関数に引数を適用Date.applyできる次のinstantiate関数を使用したいと思います:

var bind = Function.bind;
var unbind = bind.bind(bind);

function instantiate(constructor, args) {
    return new (unbind(constructor, null).apply(null, args));
}

これは、新しい日付コンストラクターを実装する方法です。

function myDate() {
    var date = instantiate(Date, arguments);
    var args = arguments.length;
    var arg = arguments[0];

    if ((args === 3 || args == 6) && arg < 100 && arg >= 0)
        date.setFullYear(arg);
    return date;
}

編集:ネイティブの Date コンストラクターをオーバーライドする場合は、次のようにする必要があります。

Date = function (Date) {
    MyDate.prototype = Date.prototype;

    return MyDate;

    function MyDate() {
        var date = instantiate(Date, arguments);
        var args = arguments.length;
        var arg = arguments[0];

        if ((args === 3 || args == 6) && arg < 100 && arg >= 0)
            date.setFullYear(arg);
        return date;
    }
}(Date);
于 2012-12-12T12:34:55.053 に答える