DefineOwnProperty.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. 'use strict';
  2. var hasPropertyDescriptors = require('has-property-descriptors');
  3. var GetIntrinsic = require('get-intrinsic');
  4. var $defineProperty = hasPropertyDescriptors() && GetIntrinsic('%Object.defineProperty%', true);
  5. var hasArrayLengthDefineBug = hasPropertyDescriptors.hasArrayLengthDefineBug();
  6. // eslint-disable-next-line global-require
  7. var isArray = hasArrayLengthDefineBug && require('../helpers/IsArray');
  8. var callBound = require('call-bind/callBound');
  9. var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
  10. // eslint-disable-next-line max-params
  11. module.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {
  12. if (!$defineProperty) {
  13. if (!IsDataDescriptor(desc)) {
  14. // ES3 does not support getters/setters
  15. return false;
  16. }
  17. if (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {
  18. return false;
  19. }
  20. // fallback for ES3
  21. if (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {
  22. // a non-enumerable existing property
  23. return false;
  24. }
  25. // property does not exist at all, or exists but is enumerable
  26. var V = desc['[[Value]]'];
  27. // eslint-disable-next-line no-param-reassign
  28. O[P] = V; // will use [[Define]]
  29. return SameValue(O[P], V);
  30. }
  31. if (
  32. hasArrayLengthDefineBug
  33. && P === 'length'
  34. && '[[Value]]' in desc
  35. && isArray(O)
  36. && O.length !== desc['[[Value]]']
  37. ) {
  38. // eslint-disable-next-line no-param-reassign
  39. O.length = desc['[[Value]]'];
  40. return O.length === desc['[[Value]]'];
  41. }
  42. $defineProperty(O, P, FromPropertyDescriptor(desc));
  43. return true;
  44. };