toFunctionName,
} from "./function.js";
import {
+ IS_CONCAT_SPREADABLE,
ITERATOR,
SPECIES,
toLength,
isSealed,
setPrototypeOf,
} = Object;
- const { [ITERATOR]: arrayIterator } = Array.prototype;
- const { next: arrayIteratorNext } = getPrototypeOf([][ITERATOR]());
const {
next: generatorIteratorNext,
} = getPrototypeOf(function* () {}.prototype);
- const splatIterablePrototype = {
- [ITERATOR]() {
- return {
- next: bind(
- arrayIteratorNext,
- call(arrayIterator, this.args, []),
- [],
- ),
- };
- },
- };
- const splatIterable = ($) =>
- create(splatIterablePrototype, { args: { value: $ } });
const propertyDescriptorEntryIterablePrototype = {
[ITERATOR]() {
return {
return {
defineOwnProperties: (O, ...sources) => {
- for (const source of splatIterable(sources)) {
- defineProperties(O, source);
+ const { length } = sources;
+ for (let index = 0; index < length; ++index) {
+ defineProperties(O, sources[index]);
}
return O;
},
}
};
+export const {
+ /**
+ * Returns whether the provided value is spreadable during array
+ * concatenation.
+ *
+ * This is also used to determine which things should be treated as
+ * collections.
+ */
+ isConcatSpreadableObject,
+} = (() => {
+ const { isArray } = Array;
+
+ return {
+ isConcatSpreadableObject: ($) => {
+ if (type($) !== "object") {
+ // The provided value is not an object.
+ return false;
+ } else {
+ // The provided value is an object.
+ const spreadable = $[IS_CONCAT_SPREADABLE];
+ return spreadable !== undefined ? !!spreadable : isArray($);
+ }
+ },
+ };
+})();
+
/**
* Returns whether the provided object is extensible.
*