gpt4 book ai didi

javascript - 将 Intl.DateTimeFormat 理解为 JavaScript 对象

转载 作者:行者123 更新时间:2023-11-29 21:03:55 24 4
gpt4 key购买 nike

我不明白 Intl.DateTimeFormat 的行为。

它没有公开我期望从 JavaScript 对象获得的行为。我想知道为什么?

以下代码片段演示了 DateTimeFormat 上的 format 方法不能被覆盖。这怎么可能?

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

通过原型(prototype)继承从 DateTimeFormat 派生似乎也是不可能的。以下代码段会引发错误:

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 对象?

DateTimeFormat 如何防止重写方法?

DateTimeFormat 如何防止覆盖派生对象?

最佳答案

原始答案

嗯,因为它是一个内置对象 - 最好将其卡住。但是你可以在 Javascript 中用 Object.defineProperty 做这样的事情.

请参阅以下截图。您可以使用 writeable: false 防止覆盖您的属性。 (我用过 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

如何防止原型(prototype)继承?

检查这个简单的片段。您可以只检查当前上下文是否与您的构造函数具有相同的原型(prototype)。

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 个的组合

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 来拯救。

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 对象一样

关于javascript - 将 Intl.DateTimeFormat 理解为 JavaScript 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45077313/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com