Understanding Intl.DateTimeFormat as a JavaScript object

此生再无相见时 提交于 2019-12-12 18:08:52

问题


I do not understand the behavior of Intl.DateTimeFormat.

It does not expose the behavior I would expect from a JavaScript object. I would like to understand why?

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

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>

Why is DateTimeFormat not behaving like a "normal" JavaScript object?

How is it possible for DateTimeFormat to prevent overriding a method?

How is it possible for DateTimeFormat to prevent overriding on a derived object?


回答1:


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.

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

How to prevent prototypal inheritance?

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

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

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! ..."

Conclusion

As we've seen with the examples. System objects behaves just like normal configured javascript objects



来源:https://stackoverflow.com/questions/45077313/understanding-intl-datetimeformat-as-a-javascript-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!