es.reflect.set.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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. // `Reflect.set` method
  13. // https://tc39.es/ecma262/#sec-reflect.set
  14. function set(target, propertyKey, V /* , receiver */) {
  15. var receiver = arguments.length < 4 ? target : arguments[3];
  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 (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;
  28. existingDescriptor.value = V;
  29. definePropertyModule.f(receiver, propertyKey, existingDescriptor);
  30. } else definePropertyModule.f(receiver, propertyKey, createPropertyDescriptor(0, V));
  31. } else {
  32. setter = ownDescriptor.set;
  33. if (setter === undefined) return false;
  34. call(setter, receiver, V);
  35. } return true;
  36. }
  37. // MS Edge 17-18 Reflect.set allows setting the property to object
  38. // with non-writable property on the prototype
  39. var MS_EDGE_BUG = fails(function () {
  40. var Constructor = function () { /* empty */ };
  41. var object = definePropertyModule.f(new Constructor(), 'a', { configurable: true });
  42. // eslint-disable-next-line es/no-reflect -- required for testing
  43. return Reflect.set(Constructor.prototype, 'a', 1, object) !== false;
  44. });
  45. $({ target: 'Reflect', stat: true, forced: MS_EDGE_BUG }, {
  46. set: set
  47. });