¡Esta es una muy buena pregunta!
La respuesta de TJ Crowder tiene una excelente solución, pero me hizo pensar: ¿Qué más podemos hacer? ¿Cómo podemos rodear elDate.prototype.setTime.call(yourFrozenDate)
?
1er intento: "Wrapper"
Una forma directa es proporcionar una AndrewDate
función que envuelva una fecha. Tiene todo lo que tiene una fecha menos los setters:
function AndrewDate(realDate) {
var proto = Date.prototype;
var propNames = Object.getOwnPropertyNames(proto)
.filter(propName => !propName.startsWith('set'));
return propNames.reduce((ret, propName) => {
ret[propName] = proto[propName].bind(realDate);
return ret;
}, {});
}
var date = AndrewDate(new Date());
date.setMonth(2);
Lo que hace es crear un objeto que tiene todas las propiedades que tiene un objeto de fecha real y utiliza Function.prototype.bind
para establecer suthis
.
Esta no es una forma infalible de reunir las llaves, pero espero que puedas ver mi intención.
Pero espera ... mirándolo un poco más aquí y allá, podemos ver que hay una mejor manera de hacer esto.
function SuperAndrewDate(realDate) {
return new Proxy(realDate, {
get(target, prop) {
if (!prop.startsWith('set')) {
return Reflect.get(target, prop);
}
}
});
}
var proxyDate = SuperAndrewDate(new Date());
¡Y lo solucionamos!
...algo así como. Mira, Firefox es el único en este momento que implementa proxies, y por algunas razones extrañas, los objetos de fecha no se pueden usar. Además, notará que aún puede hacer cosas como 'setDate' in proxyDate
y verá finalizaciones en la consola. Para superar eso, es necesario proporcionar más trampas; específicamente, has
, enumerate
, ownKeys
,getOwnPropertyDescriptor
y quién sabe qué extraños casos extremos hay!
... Entonces, pensándolo bien, esta respuesta es casi inútil. Pero al menos nos divertimos, ¿no?
Object.freeze()
todo el objeto. Parece funcionar, excepto por este problema de fecha.