DefineOwnProperty.js 1.5 KB

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