将Intl.DateTimeFormat理解为JavaScript对象 [英] Understanding Intl.DateTimeFormat as a JavaScript object

查看:331
本文介绍了将Intl.DateTimeFormat理解为JavaScript对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不了解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对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆