Is there a way to Object.freeze() a JavaScript Date?
I don't think so. You can get close, though, see under the line below. But first let's see why just Object.freeze
doesn't work.
I was expecting that calling freeze on a date would prevent changes to that date...
It would if Date
used an object property to hold its internal time value, but it doesn't. It uses a [[DateValue]]
internal slot instead. Internal slots aren't properties:
Internal slots correspond to internal state that is associated with objects and used by various ECMAScript specification algorithms. Internal slots are not object properties...
So freezing the object doesn't have any effect on its ability to mutate its [[DateValue]]
internal slot.
You can freeze a Date
, or effectively so anyway: Replace all its mutator methods with no-op functions (or functions that throw an error) and then freeze
it. But as observed by zzzzBov (nice one!), that doesn't prevent someone from doing Date.prototype.setTime.call(d, 0)
(in a deliberate attempt to get around the frozen object, or as a byproduct of some complicated code they're using). So it's close, but no cigar.
Here's an example (I'm using ES2015 features here, since I saw that let
in your code, so you'll need a recent browser to run it; but this can be done with ES5-only features as well):
"use strict";
let d = new Date();
freezeDate(d);
d.setTime(0);
snippet.log(d);
function nop() {
}
function freezeDate(d) {
allNames(d).forEach(name => {
if (name.startsWith("set") && typeof d[name] === "function") {
d[name] = nop;
}
});
Object.freeze(d);
return d;
}
function allNames(obj) {
var names = Object.create(null); // Or use Map here
var thisObj;
for (thisObj = obj; thisObj; thisObj = Object.getPrototypeOf(thisObj)) {
Object.getOwnPropertyNames(thisObj).forEach(name => {
names[name] = 1;
});
}
return Object.keys(names);
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…