OrdinaryDefineOwnProperty.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $gOPD = require('gopd');
  4. var $SyntaxError = GetIntrinsic('%SyntaxError%');
  5. var $TypeError = GetIntrinsic('%TypeError%');
  6. var isPropertyDescriptor = require('../helpers/isPropertyDescriptor');
  7. var IsAccessorDescriptor = require('./IsAccessorDescriptor');
  8. var IsDataDescriptor = require('./IsDataDescriptor');
  9. var IsExtensible = require('./IsExtensible');
  10. var IsPropertyKey = require('./IsPropertyKey');
  11. var ToPropertyDescriptor = require('./ToPropertyDescriptor');
  12. var SameValue = require('./SameValue');
  13. var Type = require('./Type');
  14. var ValidateAndApplyPropertyDescriptor = require('./ValidateAndApplyPropertyDescriptor');
  15. // https://262.ecma-international.org/6.0/#sec-ordinarydefineownproperty
  16. module.exports = function OrdinaryDefineOwnProperty(O, P, Desc) {
  17. if (Type(O) !== 'Object') {
  18. throw new $TypeError('Assertion failed: O must be an Object');
  19. }
  20. if (!IsPropertyKey(P)) {
  21. throw new $TypeError('Assertion failed: P must be a Property Key');
  22. }
  23. if (!isPropertyDescriptor({
  24. Type: Type,
  25. IsDataDescriptor: IsDataDescriptor,
  26. IsAccessorDescriptor: IsAccessorDescriptor
  27. }, Desc)) {
  28. throw new $TypeError('Assertion failed: Desc must be a Property Descriptor');
  29. }
  30. if (!$gOPD) {
  31. // ES3/IE 8 fallback
  32. if (IsAccessorDescriptor(Desc)) {
  33. throw new $SyntaxError('This environment does not support accessor property descriptors.');
  34. }
  35. var creatingNormalDataProperty = !(P in O)
  36. && Desc['[[Writable]]']
  37. && Desc['[[Enumerable]]']
  38. && Desc['[[Configurable]]']
  39. && '[[Value]]' in Desc;
  40. var settingExistingDataProperty = (P in O)
  41. && (!('[[Configurable]]' in Desc) || Desc['[[Configurable]]'])
  42. && (!('[[Enumerable]]' in Desc) || Desc['[[Enumerable]]'])
  43. && (!('[[Writable]]' in Desc) || Desc['[[Writable]]'])
  44. && '[[Value]]' in Desc;
  45. if (creatingNormalDataProperty || settingExistingDataProperty) {
  46. O[P] = Desc['[[Value]]']; // eslint-disable-line no-param-reassign
  47. return SameValue(O[P], Desc['[[Value]]']);
  48. }
  49. throw new $SyntaxError('This environment does not support defining non-writable, non-enumerable, or non-configurable properties');
  50. }
  51. var desc = $gOPD(O, P);
  52. var current = desc && ToPropertyDescriptor(desc);
  53. var extensible = IsExtensible(O);
  54. return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current);
  55. };