es.reflect.set.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. 'use strict';
  2. var $ = require('../internals/export');
  3. var call = require('../internals/function-call');
  4. var anObject = require('../internals/an-object');
  5. var isObject = require('../internals/is-object');
  6. var isDataDescriptor = require('../internals/is-data-descriptor');
  7. var fails = require('../internals/fails');
  8. var definePropertyModule = require('../internals/object-define-property');
  9. var getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');
  10. var getPrototypeOf = require('../internals/object-get-prototype-of');
  11. var createPropertyDescriptor = require('../internals/create-property-descriptor');
  12. var toPropertyKey = require('../internals/to-property-key');
  13. // `Reflect.set` method
  14. // https://tc39.es/ecma262/#sec-reflect.set
  15. var $set = function (target, propertyKey, V, receiver) {
  16. var ownDescriptor = getOwnPropertyDescriptorModule.f(anObject(target), propertyKey);
  17. var existingDescriptor, prototype, setter;
  18. if (!ownDescriptor) {
  19. if (isObject(prototype = getPrototypeOf(target))) {
  20. return $set(prototype, propertyKey, V, receiver);
  21. }
  22. ownDescriptor = createPropertyDescriptor(0);
  23. }
  24. if (isDataDescriptor(ownDescriptor)) {
  25. if (ownDescriptor.writable === false || !isObject(receiver)) return false;
  26. if (existingDescriptor = getOwnPropertyDescriptorModule.f(receiver, propertyKey)) {
  27. if (!isDataDescriptor(existingDescriptor) || existingDescriptor.writable === false) return false;
  28. definePropertyModule.f(receiver, propertyKey, { value: V });
  29. } else try {
  30. definePropertyModule.f(receiver, propertyKey, createPropertyDescriptor(0, V));
  31. } catch (error) {
  32. return false;
  33. }
  34. } else {
  35. setter = ownDescriptor.set;
  36. if (setter === undefined) return false;
  37. call(setter, receiver, V);
  38. } return true;
  39. };
  40. // MS Edge 17-18 Reflect.set allows setting the property to object
  41. // with non-writable property on the prototype
  42. var MS_EDGE_BUG = fails(function () {
  43. var Constructor = function () { /* empty */ };
  44. var object = definePropertyModule.f(new Constructor(), 'a', { configurable: true });
  45. // eslint-disable-next-line es/no-reflect -- required for testing
  46. return Reflect.set(Constructor.prototype, 'a', 1, object) !== false;
  47. });
  48. $({ target: 'Reflect', stat: true, forced: MS_EDGE_BUG }, {
  49. set: function set(target, propertyKey, V /* , receiver */) {
  50. return $set(anObject(target), toPropertyKey(propertyKey), V, arguments.length < 4 ? target : arguments[3]);
  51. }
  52. });