C'est bien pour étendre les "classes customs" qui se basent sur le constructeur de function
mais pas pour les éléments natifs (Array
, Date
, etc). On ne peut pas, ou presque, les étendre.
Date.UTC(2012,02,30); // ok
MyDate.UTC(2012,02,30); // has no method 'UTC'
var d = new MyDate();
console.log(d.getHours()); // this is not a Date object.
Car, en dur dans le moteur Javascript, chaque méthode de Date va vérifier que l'objet en question est bien une instance de Date
. Voici un extrait du code V8
(pour prendre un moteur en exemple) :
function DateGetHours() {
var t = DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) return t;
return HOUR_FROM_TIME(LocalTimeNoCheck(t));
}
où DATE_VALUE
est une macro :
DATE_VALUE(arg) = (%_ClassOf(arg) === 'Date' ? %_ValueOf(arg) : ThrowDateTypeError());
, qui check donc si l'objet passé est bien une instance de Date
.
Vérification : (ça affiche la propriété interne [[Class]]
qui permet de catégoriser les objets JS en fonction de leur instanciation)
Object.prototype.toString.call(new Date()); // Date
Object.prototype.toString.call(new MyDate()); // Object
Donc, si une date n'est pas instanciée en utilisant new Date()
, l'objet ne sera pas une Date
et ne pourra pas être manipulé comme tel. Contrairement aux autres "wrappers" JS, Date
n'a pas de syntaxe littéral tels que new Object
=> {}
, new Array
=> []
, new Number
=> 1
, new String()
=> ""
, etc.