When the *iterateKeys* function is called with argument _O_, the following steps are taken:
15 |
16 | 1. Let _obj_ be ? ToObject(_O_).
17 | 1. Let _nameList_ be ? EnumerableOwnProperties(_obj_, ~key~).
18 | 1. Return CreateArrayIterator(CreateArrayFromList(_nameList_), ~key~).
19 |
20 |
21 |
22 |
23 |
Object.iterateValues( O )
24 |
When the *iterateValues* function is called with argument _O_, the following steps are taken:
25 |
26 | 1. Let _obj_ be ? ToObject(_O_).
27 | 1. Let _valueList_ be ? EnumerableOwnProperties(_obj_, ~value~).
28 | 1. Return CreateArrayIterator(CreateArrayFromList(_valueList_), ~value~).
29 |
30 |
31 |
32 |
33 |
Object.iterateEntries( O )
34 |
When the *iterateEntries* function is called with argument _O_, the following steps are taken:
35 |
36 | 1. Let _obj_ be ? ToObject(_O_).
37 | 1. Let _entryList_ be ? EnumerableOwnProperties(_obj_, ~key+value~).
38 | 1. Return CreateArrayIterator(CreateArrayFromList(_entryList_), ~key+value~).
39 |
40 |
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WITHDRAWN: This proposal has been withdrawn from consideration
2 |
3 | After concerns were raised at the February 2020 meeting, this proposal is being withdrawn.
4 |
5 | # Improving iteration on Objects
6 |
7 | An ECMA TC39 proposal to improve the experience & performance of iterating and mapping over Objects
8 |
9 | ## Vitals
10 |
11 | - **Current stage:** 1
12 | - **Last presented:** February 2020
13 | - **Next presentation:** TBD
14 | - **Author:** Jonathan Keslin (@decompil3d) -- GoDaddy
15 | - **Champion:** Jonathan Keslin (@decompil3d) -- GoDaddy
16 |
17 | ## The problem
18 |
19 | Objects are commonly used as the defacto dictionary type in Javascript. But Objects are not iterable by default, so
20 | many of the valuable collection methods on Iterables are not available for Objects without first transforming the
21 | Object into an Array[1](#footnote-1).
22 |
23 | ## Proposed solution
24 |
25 | ### Provide functionality to get an `Iterator` on an Object
26 |
27 | ```js
28 | // Collect result back into an Object
29 | Object.fromEntries(
30 | // Utility method to get an iterator on an Object
31 | Object.iterateEntries(obj)
32 | // Standard `map` function that operates on iterables
33 | .map(([key, value]) => [transform(key), transform(value)])
34 | );
35 | ```
36 |
37 | ### What exactly is being proposed
38 |
39 | - Adding up to three static methods on `Object` to provide in-place iteration on data stored therein:
40 | - `Object.iterateEntries`: iterates through the Object, providing key-value pairs much like `Map.prototype.entries`
41 | - `Object.iterateKeys`: iterates through the Object, providing just the keys like `Map.prototype.keys`
42 | - `Object.iterateValues`: iterates through the Object, providing just the values like `Map.prototype.values`
43 |
44 | #### `Object.iterateEntries`
45 |
46 | ```js
47 | const obj = { foo: 'bar', baz: 'blah' };
48 | const entriesIterator = Object.iterateEntries(obj);
49 | for (const [key, value] of entriesIterator) {
50 | console.log(`${key} -> ${value}`);
51 | }
52 | ```
53 |
54 | #### `Object.iterateKeys`
55 |
56 | ```js
57 | const obj = { foo: 'bar', baz: 'blah' };
58 | const keysIterator = Object.iterateKeys(obj);
59 | for (const key of keysIterator) {
60 | console.log(key);
61 | }
62 | ```
63 |
64 | #### `Object.iterateValues`
65 |
66 | ```js
67 | const obj = { foo: 'bar', baz: 'blah' };
68 | const valuesIterator = Object.iterateValues(obj);
69 | for (const value of valuesIterator) {
70 | console.log(value);
71 | }
72 | ```
73 |
74 | #### Relationship to the existing [Iterator Helpers] proposal
75 |
76 | - The [Iterator Helpers] proposal is not a requirement to make this proposal useful, but it substantially improves
77 | developer experience
78 | - Without this proposal, the helpers provided in [Iterator Helpers] are not as valuable for data stored in Objects,
79 | as there are currently no mechanisms to in-place iterate through an Object.
80 |
81 | ## Polyfill
82 |
83 | An unofficial polyfill is available in the [core-js](https://github.com/zloirock/core-js#object-iteration) library.
84 |
85 | ## History of this proposal
86 |
87 | This proposal has morphed a bit since original presentation.
88 |
89 | ### October 2019
90 |
91 | The initial proposal was `Object.map` -- providing a static API method on `Object` to transform the keys and/or values
92 | and return the transformed Object.
93 |
94 | Slides:
95 |
96 | #### Resolution from the meeting
97 |
98 | There was general support for improving the experience and optimizability of mapping over Objects, but folks were
99 | concerned about the slippery slope that adding a `map` method would create.
100 |
101 | Instead, we agreed that the proposal could change to be an exploration on improving mapping over Objects and agreed on
102 | Stage 1.
103 |
104 | #### After meeting discussion
105 |
106 | After the October meeting, the champions & authors of this proposal and the [Iterator Helpers] proposal met and
107 | discussed how the two proposals are related. It was determined that augmenting `Iterator.from` for this purpose
108 | would not work, since it would be ambiguous for Objects that extend `Iterator.prototype`.
109 |
110 | Since [Iterator Helpers] provides the needed `map` mechanism, this proposal could be adjusted to focus on getting
111 | an `Iterator` from an Object.
112 |
113 | ### February 2020
114 |
115 | Presented the change from "Object mapping" to "Object iteration"
116 |
117 | Slides:
118 |
119 | Proposed spec text:
120 |
121 | Alternate spec text:
122 |
123 | #### Resolution from the meeting
124 |
125 | Multiple implementors voiced concerns over the usefulness of this API. Folks believe that the existing `Object.keys`,
126 | `values`, and `entries` are just fine and can be optimized easily enough. It's straightforward enough for an engine
127 | to have a "fast" path that can just optimize away the array instantiation in the common case, with a slower path for
128 | edge cases like when the Array prototype is polluted.
129 |
130 | There was also concern over the second spec text option allowing modification of the underlying object during iteration.
131 | This is consistent with existing collections such as Array, Set, and Map. But it would mean that moving from using `keys`
132 | to `iterateKeys` would have a real semantic difference that could be a footgun.
133 |
134 | Some delegates believe that it would be better to try to direct folks to more appropriate "dictionary" collections like
135 | `Map`, which already provides the in-place iteration provided in the proposal as presented. There was agreement that
136 | getting `Map`s from JSON was not ideal, so the next steps for this proposal may be to investigate improving revivers for
137 | this purpose.
138 |
139 | More investigation to follow.
140 |
141 | ##### Notes
142 |
143 | 1 Specifically, `Object.entries`, `Object.keys`, and `Object.values`
144 |
145 | [Iterator Helpers]: https://github.com/tc39/proposal-iterator-helpers
146 |
--------------------------------------------------------------------------------
/alt.emu:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
An Object Iterator is an object, that represents a specific iteration over some specific instance object. There is not a named constructor for Object Iterator objects. Instead, Object Iterator objects are created by calling certain methods of the Object global.
42 |
43 |
44 |
CreateObjectIterator ( _obj_, _kind_ )
45 |
Several methods of the Object global return Iterator objects. The abstract operation CreateObjectIterator with arguments _obj_ and _kind_ is used to create such iterator objects. It performs the following steps:
46 |
47 | 1. Let _iterator_ be ObjectCreate(%ObjectIteratorPrototype%, « [[IteratedObject]], [[ObjectNextIndex]], [[ObjectIterationKind]] »).
48 | 1. Set _iterator_.[[IteratedObject]] to _obj_.
49 | 1. Set _iterator_.[[ObjectNextIndex]] to 0.
50 | 1. Set _iterator_.[[ObjectIterationKind]] to _kind_.
51 | 1. Return _iterator_.
52 |
53 |
54 |
55 |
56 |
The %ObjectIteratorPrototype% Object
57 |
The %ObjectIteratorPrototype% object:
58 |
59 |
has properties that are inherited by all Object Iterator Objects.
60 |
is an ordinary object.
61 |
has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
62 |
has the following properties:
63 |
64 |
65 |
66 |
%ObjectIteratorPrototype%.next ( )
67 |
68 | 1. Let _O_ be the *this* value.
69 | 1. If Type(_O_) is not Object, throw a *TypeError* exception.
70 | 1. If _O_ does not have all of the internal slots of a Object Iterator Instance (), throw a *TypeError* exception.
71 | 1. Let _obj_ be _O_.[[IteratedObject]].
72 | 1. Let _index_ be _O_.[[ObjectNextIndex]].
73 | 1. Let _itemKind_ be _O_.[[ObjectIterationKind]].
74 | 1. If _obj_ is *undefined*, return CreateIterResultObject(*undefined*, *true*).
75 | 1. Let _items_ be ? EnumerableOwnProperties(_obj_, _kind_).
76 | 1. Let _numItems_ be the number of elements of _items_.
77 | 1. NOTE: _numItems_ must be redetermined each time this method is evaluated.
78 | 1. Repeat, while _index_ is less than _numItems_,
79 | 1. Let _i_ be the Record that is the value of _items_[_index_].
80 | 1. Set _index_ to _index_ + 1.
81 | 1. Set _O_.[[ObjectNextIndex]] to _index_.
82 | 1. Return CreateIterResultObject(_i_, *false*).
83 | 1. Set _O_.[[IteratedObject]] to *undefined*.
84 | 1. Return CreateIterResultObject(*undefined*, *true*).
85 |
86 |
87 |
88 |
89 |
%ObjectIteratorPrototype% [ @@toStringTag ]
90 |
The initial value of the @@toStringTag property is the String value *"Object Iterator"*.
91 |
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
92 |
93 |
94 |
95 |
96 |
Properties of Object Iterator Instances
97 |
Object Iterator instances are ordinary objects that inherit properties from the %ObjectIteratorPrototype% intrinsic object. Object Iterator instances are initially created with the internal slots described in .
98 |
99 |
100 |
101 |
102 |
103 | Internal Slot
104 |
105 |
106 | Description
107 |
108 |
109 |
110 |
111 | [[IteratedObject]]
112 |
113 |
114 | The object that is being iterated.
115 |
116 |
117 |
118 |
119 | [[ObjectNextIndex]]
120 |
121 |
122 | The integer index of the next enumerable element to be examined by this iterator.
123 |
124 |
125 |
126 |
127 | [[ObjectIterationKind]]
128 |
129 |
130 | A String value that identifies what is returned for each element of the iteration. The possible values are: ~key~, ~value~, ~key+value~.
131 |
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
1837 |
1838 |
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1839 |
1840 |
1841 |
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1842 |
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
1843 |
Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.
1844 |
1845 |
1846 |
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
An Object Iterator is an object, that represents a specific iteration over some specific instance object. There is not a named constructor for Object Iterator objects. Instead, Object Iterator objects are created by calling certain methods of the Object global.
1834 |
1835 |
1836 |
4.1CreateObjectIterator ( obj, kind )
1837 |
Several methods of the Object global return Iterator objects. The abstract operation CreateObjectIterator with arguments obj and kind is used to create such iterator objects. It performs the following steps:
The initial value of the @@toStringTag property is the String value "Object Iterator".
1861 |
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
1862 |
1863 |
1864 |
1865 |
1866 |
4.3Properties of Object Iterator Instances
1867 |
Object Iterator instances are ordinary objects that inherit properties from the %ObjectIteratorPrototype% intrinsic object. Object Iterator instances are initially created with the internal slots described in Table 1.
1868 |
Table 1: Internal Slots of Object Iterator Instances
1869 |
1870 |
1871 |
1872 |
1873 | Internal Slot
1874 |
1875 |
1876 |
1877 | Description
1878 |
1879 |
1880 |
1881 |
1882 |
1883 | [[IteratedObject]]
1884 |
1885 |
1886 |
1887 | The object that is being iterated.
1888 |
1889 |
1890 |
1891 |
1892 |
1893 | [[ObjectNextIndex]]
1894 |
1895 |
1896 |
1897 | The integer index of the next enumerable element to be examined by this iterator.
1898 |
1899 |
1900 |
1901 |
1902 |
1903 | [[ObjectIterationKind]]
1904 |
1905 |
1906 |
1907 | A String value that identifies what is returned for each element of the iteration. The possible values are: key, value, key+value.
1908 |
1909 |
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
1923 |
1924 |
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1925 |
1926 |
1927 |
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1928 |
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
1929 |
Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.
1930 |
1931 |
1932 |
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.