OrdinaryDefineOwnProperty.js 2.1 KB

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