DefineOwnProperty.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
  4. if ($defineProperty) {
  5. try {
  6. $defineProperty({}, 'a', { value: 1 });
  7. } catch (e) {
  8. // IE 8 has a broken defineProperty
  9. $defineProperty = null;
  10. }
  11. }
  12. // node v0.6 has a bug where array lengths can be Set but not Defined
  13. var hasArrayLengthDefineBug;
  14. try {
  15. hasArrayLengthDefineBug = $defineProperty && $defineProperty([], 'length', { value: 1 }).length === 0;
  16. } catch (e) {
  17. // In Firefox 4-22, defining length on an array throws an exception.
  18. hasArrayLengthDefineBug = true;
  19. }
  20. // eslint-disable-next-line global-require
  21. var isArray = hasArrayLengthDefineBug && require('../2020/IsArray'); // this does not depend on any other AOs.
  22. var callBound = require('call-bind/callBound');
  23. var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
  24. // eslint-disable-next-line max-params
  25. module.exports = function DefineOwnProperty(IsDataDescriptor, SameValue, FromPropertyDescriptor, O, P, desc) {
  26. if (!$defineProperty) {
  27. if (!IsDataDescriptor(desc)) {
  28. // ES3 does not support getters/setters
  29. return false;
  30. }
  31. if (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {
  32. return false;
  33. }
  34. // fallback for ES3
  35. if (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {
  36. // a non-enumerable existing property
  37. return false;
  38. }
  39. // property does not exist at all, or exists but is enumerable
  40. var V = desc['[[Value]]'];
  41. // eslint-disable-next-line no-param-reassign
  42. O[P] = V; // will use [[Define]]
  43. return SameValue(O[P], V);
  44. }
  45. if (
  46. hasArrayLengthDefineBug
  47. && P === 'length'
  48. && '[[Value]]' in desc
  49. && isArray(O)
  50. && O.length !== desc['[[Value]]']
  51. ) {
  52. // eslint-disable-next-line no-param-reassign
  53. O.length = desc['[[Value]]'];
  54. return O.length === desc['[[Value]]'];
  55. }
  56. $defineProperty(O, P, FromPropertyDescriptor(desc));
  57. return true;
  58. };