Đây thực sự là một câu hỏi tốt!
Câu trả lời của TJ Crowder có một giải pháp tuyệt vời, nhưng nó khiến tôi phải suy nghĩ: Chúng ta có thể làm gì khác? Làm thế nào chúng ta có thể đi xung quanh Date.prototype.setTime.call(yourFrozenDate)
?
Lần thử đầu tiên: "Wrapper"
Một cách trực tiếp là cung cấp một AndrewDate
hàm kết thúc một ngày tháng. Nó có tất cả mọi thứ mà một ngày có trừ những người thiết lập:
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);
Điều này làm là tạo một đối tượng có tất cả các thuộc tính mà một đối tượng ngày tháng thực tế có và sử dụng Function.prototype.bind
để thiết lập chúng this
.
Đây không phải là một bằng chứng ngu ngốc để thu thập các phím, nhưng hy vọng bạn có thể thấy ý định của tôi.
Nhưng khoan đã ... nhìn xa hơn một chút ở đây và ở đó, chúng ta có thể thấy rằng có một cách tốt hơn để làm điều này.
Lần thử thứ 2: Proxy
function SuperAndrewDate(realDate) {
return new Proxy(realDate, {
get(target, prop) {
if (!prop.startsWith('set')) {
return Reflect.get(target, prop);
}
}
});
}
var proxyDate = SuperAndrewDate(new Date());
Và chúng tôi đã giải quyết nó!
... đại loại. Hãy xem, Firefox là phiên bản duy nhất hiện nay cài đặt proxy và vì một số lý do kỳ lạ không thể proxy đối tượng date. Hơn nữa, bạn sẽ nhận thấy rằng bạn vẫn có thể làm những việc như thế 'setDate' in proxyDate
và bạn sẽ thấy các hoàn thành trong bảng điều khiển. Để vượt qua điều đó cần cung cấp nhiều bẫy hơn; Cụ thể, has
, enumerate
, ownKeys
, getOwnPropertyDescriptor
và ai biết được những gì trường hợp cạnh lạ có!
... Vì vậy, suy nghĩ lại, câu trả lời này gần như vô nghĩa. Nhưng ít nhất chúng ta đã vui vẻ, phải không?
Object.freeze()
trên toàn bộ đối tượng. Nó có vẻ hoạt động, ngoại trừ vấn đề Ngày tháng vui nhộn này.