es2018.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. 'use strict';
  2. var bind = require('function-bind');
  3. var keys = require('object-keys');
  4. var ES2017 = require('./es2017');
  5. var assign = require('./helpers/assign');
  6. var forEach = require('./helpers/forEach');
  7. var GetIntrinsic = require('./GetIntrinsic');
  8. var $String = GetIntrinsic('%String%');
  9. var $Object = GetIntrinsic('%Object%');
  10. var $SymbolProto = GetIntrinsic('%SymbolPrototype%', true);
  11. var $SymbolValueOf = $SymbolProto ? bind.call(Function.call, $SymbolProto.valueOf) : null;
  12. var $StringProto = GetIntrinsic('%StringPrototype%');
  13. var $charAt = bind.call(Function.call, $StringProto.charAt);
  14. var $PromiseResolveOrig = GetIntrinsic('%Promise_resolve%', true);
  15. var $PromiseResolve = $PromiseResolveOrig ? bind.call(Function.call, $PromiseResolveOrig) : null;
  16. var $isEnumerable = bind.call(Function.call, GetIntrinsic('%ObjectPrototype%').propertyIsEnumerable);
  17. var $pushApply = bind.call(Function.apply, GetIntrinsic('%ArrayPrototype%').push);
  18. var $gOPS = $SymbolValueOf ? $Object.getOwnPropertySymbols : null;
  19. var OwnPropertyKeys = function OwnPropertyKeys(ES, source) {
  20. var ownKeys = keys(source);
  21. if ($gOPS) {
  22. $pushApply(ownKeys, $gOPS(source));
  23. }
  24. return ownKeys;
  25. };
  26. var ES2018 = assign(assign({}, ES2017), {
  27. EnumerableOwnPropertyNames: ES2017.EnumerableOwnProperties,
  28. // https://ecma-international.org/ecma-262/9.0/#sec-thissymbolvalue
  29. thisSymbolValue: function thisSymbolValue(value) {
  30. if (!$SymbolValueOf) {
  31. throw new SyntaxError('Symbols are not supported; thisSymbolValue requires that `value` be a Symbol or a Symbol object');
  32. }
  33. if (this.Type(value) === 'Symbol') {
  34. return value;
  35. }
  36. return $SymbolValueOf(value);
  37. },
  38. // https://www.ecma-international.org/ecma-262/9.0/#sec-isstringprefix
  39. IsStringPrefix: function IsStringPrefix(p, q) {
  40. if (this.Type(p) !== 'String') {
  41. throw new TypeError('Assertion failed: "p" must be a String');
  42. }
  43. if (this.Type(q) !== 'String') {
  44. throw new TypeError('Assertion failed: "q" must be a String');
  45. }
  46. if (p === q || p === '') {
  47. return true;
  48. }
  49. var pLength = p.length;
  50. var qLength = q.length;
  51. if (pLength >= qLength) {
  52. return false;
  53. }
  54. // assert: pLength < qLength
  55. for (var i = 0; i < pLength; i += 1) {
  56. if ($charAt(p, i) !== $charAt(q, i)) {
  57. return false;
  58. }
  59. }
  60. return true;
  61. },
  62. // https://www.ecma-international.org/ecma-262/9.0/#sec-tostring-applied-to-the-number-type
  63. NumberToString: function NumberToString(m) {
  64. if (this.Type(m) !== 'Number') {
  65. throw new TypeError('Assertion failed: "m" must be a String');
  66. }
  67. return $String(m);
  68. },
  69. // https://www.ecma-international.org/ecma-262/9.0/#sec-copydataproperties
  70. CopyDataProperties: function CopyDataProperties(target, source, excludedItems) {
  71. if (this.Type(target) !== 'Object') {
  72. throw new TypeError('Assertion failed: "target" must be an Object');
  73. }
  74. if (!this.IsArray(excludedItems)) {
  75. throw new TypeError('Assertion failed: "excludedItems" must be a List of Property Keys');
  76. }
  77. for (var i = 0; i < excludedItems.length; i += 1) {
  78. if (!this.IsPropertyKey(excludedItems[i])) {
  79. throw new TypeError('Assertion failed: "excludedItems" must be a List of Property Keys');
  80. }
  81. }
  82. if (typeof source === 'undefined' || source === null) {
  83. return target;
  84. }
  85. var ES = this;
  86. var fromObj = ES.ToObject(source);
  87. var sourceKeys = OwnPropertyKeys(ES, fromObj);
  88. forEach(sourceKeys, function (nextKey) {
  89. var excluded = false;
  90. forEach(excludedItems, function (e) {
  91. if (ES.SameValue(e, nextKey) === true) {
  92. excluded = true;
  93. }
  94. });
  95. var enumerable = $isEnumerable(fromObj, nextKey) || (
  96. // this is to handle string keys being non-enumerable in older engines
  97. typeof source === 'string'
  98. && nextKey >= 0
  99. && ES.IsInteger(ES.ToNumber(nextKey))
  100. );
  101. if (excluded === false && enumerable) {
  102. var propValue = ES.Get(fromObj, nextKey);
  103. ES.CreateDataProperty(target, nextKey, propValue);
  104. }
  105. });
  106. return target;
  107. },
  108. // https://ecma-international.org/ecma-262/9.0/#sec-promise-resolve
  109. PromiseResolve: function PromiseResolve(C, x) {
  110. if (!$PromiseResolve) {
  111. throw new SyntaxError('This environment does not support Promises.');
  112. }
  113. return $PromiseResolve(C, x);
  114. }
  115. });
  116. delete ES2018.EnumerableOwnProperties; // replaced with EnumerableOwnPropertyNames
  117. delete ES2018.IsPropertyDescriptor; // not an actual abstract operation
  118. module.exports = ES2018;