问题描述
我不了解Intl.DateTimeFormat
的行为.
它没有暴露我期望从JavaScript对象获得的行为.我想知道为什么吗?
It does not expose the behavior I would expect from a JavaScript object.I would like to understand why?
以下代码片段演示了DateTimeFormat
上的format
方法不能被覆盖.这怎么可能?
The following snippet demonstrates that the format
method on DateTimeFormat
can't be overridden. How is this possible?
const itDateTimeFormat1 = new window.Intl.DateTimeFormat('it-CH');
const originalFormat = itDateTimeFormat1.format;
itDateTimeFormat1.format = function(date){ return 'Overriden! ' + originalFormat(date)};
console.log(itDateTimeFormat1.format(new Date())); // -> 13/7/2017
似乎也不可能通过原型继承从DateTimeFormat
派生.以下代码段引发错误:
Also deriving from DateTimeFormat
via prototypal inheritance seems not possible. The following snippet throws an error:
const itDateTimeFormat2 = new window.Intl.DateTimeFormat('it-CH');
const wrappedDateTimeFormat = Object.create(itDateTimeFormat2);
wrappedDateTimeFormat.format = function(date){ return 'Overriden! ' };
console.log(wrappedDateTimeFormat.format(new Date()));
// Firefox:
// TypeError: Intl.DateTimeFormat.prototype.format called on value that's not an object initialized as a DateTimeFormat
// Chrome:
// Uncaught TypeError: Method format called on incompatible receiver #<DateTimeFormat>
为什么DateTimeFormat
的行为不像普通" JavaScript对象?
Why is DateTimeFormat
not behaving like a "normal" JavaScript object?
DateTimeFormat
如何防止覆盖方法?
DateTimeFormat
如何防止对派生对象进行覆盖?
How is it possible for DateTimeFormat
to prevent overriding on a derived object?
推荐答案
原始答案
好吧,因为它是一个内置对象-冻结它是很好的.但是,您可以使用对象在Javascript中执行类似的操作.defineProperty .
Original answer
Well, since it's a built-in object - it is good to have it frozen.But you can do things like this just in Javascript with Object.defineProperty.
请参阅以下快照程序.您可以使用writeable: false
防止覆盖属性. (我使用过JS 5.1)
See the following snipper. You can prevent override of your properties with writeable: false
. (I've used JS 5.1)
var MyCoolConstructor = function () {
Object.defineProperty(this, 'nonWriteable', {
enumerable: false,
configurable: false,
writable: false,
value: function () {return 42;}
});
};
var instance = new MyCoolConstructor();
console.log(instance.nonWriteable()); //42
instance.nonWriteable = function () {return 'overriden';}
console.log(instance.nonWriteable()); //42
如何防止原型继承?
检查此简单代码段.您只需检查当前上下文是否具有与构造函数相同的原型即可.
Check this simple snippet. You can just check if current context have the same prototype as your constructor.
var MyCoolConstructor = function () {
this.foo = function () {
if (Object.getPrototypeOf(this) === MyCoolConstructor.prototype) {
return 42;
} else {
throw new Error('bad this');
}
};
};
var instance = new MyCoolConstructor();
console.log(instance.foo());
//42
var instance2 = Object.create(instance);
console.log(instance2.foo())
//Bad this
编辑2
也可以以相同的方式防止派生对象方法的覆盖,他们派生属性配置.检查此代码段,该代码段是前2个的组合
Edit 2
Derived object method override can also be prevented in the same manner,they derive property config.Check this snippet which is combination of previous 2
var MyCoolConstructor = function () {
Object.defineProperty(this, 'foo', {
value: function () {
if (Object.getPrototypeOf(this) === MyCoolConstructor.prototype) {
return 42;
} else {
throw new Error('bad this');
}
},
writeable: false
});
};
var instance = new MyCoolConstructor();
console.log(instance.foo());
//42
var derivedInstance = Object.create(instance);
derivedInstance.foo = function () {
return 'overriden';
};
console.log(derivedInstance.foo());
//Bad this. Can't be overridden because foo property is not writeable
在3 .. 2 .. 1 ...
中不是很酷的技巧如果您真的想覆盖smth,请Object.defineProperty
进行救援.
Not cool hacks in 3.. 2.. 1..
If you really want to override smth, Object.defineProperty
come to the rescue.
const itDateTimeFormat2 = new window.Intl.DateTimeFormat('it-CH');
const wrappedDateTimeFormat = Object.create(itDateTimeFormat2);
Object.defineProperty(wrappedDateTimeFormat, 'format', {value: function(date) { return 'Overridden!' + date.toString(); }})
wrappedDateTimeFormat.format()
//"Overriden! ..."
结论
正如我们在示例中看到的那样.系统对象的行为就像正常配置的javascript对象一样
Conclusion
As we've seen with the examples. System objects behaves just like normal configured javascript objects
这篇关于将Intl.DateTimeFormat理解为JavaScript对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!