将Intl.DateTimeFormat理解为JavaScript对象

将Intl.DateTimeFormat理解为JavaScript对象,javascript,datetime-format,ecmascript-intl,Javascript,Datetime Format,Ecmascript Intl,我不理解Intl.DateTimeFormat的行为 它没有公开我期望从JavaScript对象中获得的行为。 我想知道为什么 下面的代码片段演示了不能重写DateTimeFormat上的format方法。这怎么可能 const itDateTimeFormat1 = new window.Intl.DateTimeFormat('it-CH'); const originalFormat = itDateTimeFormat1.format; itDateTimeFormat1.format

我不理解
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
通过原型继承从
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>
const itDateTimeFormat2=newwindow.Intl.DateTimeFormat('it-CH');
const wrappedDataTimeFormat=Object.create(itDateTimeFormat2);
wrappedDataTimeFormat.format=函数(日期){return'overrided!'};
log(wrappedDataTimeFormat.format(newDate());
//火狐:
//TypeError:Intl.DateTimeFormat.prototype.format调用的值不是初始化为DateTimeFormat的对象
//铬:
//未捕获的TypeError:在不兼容的接收器上调用的方法格式#
为什么
DateTimeFormat
的行为不像一个“正常”的JavaScript对象

DateTimeFormat
如何防止重写方法

DateTimeFormat
如何防止在派生对象上重写?

原始答案 好吧,因为它是一个内置对象-最好将其冻结。 但是您可以使用Javascript和

请参阅下面的snipper。您可以使用
writeable:false
防止重写属性。(我用过JS5.1)

如何防止原型遗传

检查这个简单的代码片段。您只需检查当前上下文是否与构造函数具有相同的原型

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 派生对象方法重写也可以以相同的方式防止, 它们派生属性配置。 检查此代码段,它是前两个代码段的组合

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

谢谢,这解释了很多。然而,在
DateTimeFormat
的情况下,派生对象似乎不能提供自己的
format
方法(我调整了问题中的第二个片段)。这是怎么可能的?@jbandi让我想想:)我将尝试为这种行为提供一个片段,还有一些很棒的例子!谢谢
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! ..."