0

Recently, I've decided to get into the nitty gritty of JS benchmarking, and decided that to defeat the native reverse function, I should understand what it does under the hood.

I've been reading through the ECMAscript docs for array.prototype.reverse, and although the syntax used is somewhat mystifying, I've gathered the method performs a half loop and sets the upper bound to length -1 -i, which is the way I would do it. Inside the loop, I think the actual value swap is handled by the following code:

If lowerExists is true and upperExists is true, then
Perform ? Set(O, lowerP, upperValue, true).
Perform ? Set(O, upperP, lowerValue, true).

The Set ( O, P, V, Throw ) method appears to be an action verb, in that it actually sets a value. Let's take a closer look.

The abstract operation Set takes arguments O (an Object), P (a property key), V (an ECMAScript language value), and Throw (a Boolean). It is used to set the value of a specific property of an object. V is the new value for the property. It performs the following steps when called:

Assert: Type(O) is Object.
Assert: IsPropertyKey(P) is true.
Assert: Type(Throw) is Boolean.
Let success be ? O.[[Set]](P, V, O).
If success is false and Throw is true, throw a TypeError exception.
Return success.

A problem arises when we get to line 4: the function is defined in terms of itself.

My questions are:

  1. What does array.prototype.reverse do under the hood, and am I looking in the right place for that?
  2. Is Set ( O, P, V, Throw ) equivalent to map.set(k,v)?
  3. What efficiencies are gained by using the Set ( O, P, V, Throw ) method? Is this literally the method used, or is this just an abstract representation of some magic performed by the engine?
  4. Can the entire reverse() function be (faithfully) recreated in regular javascript code, and what would that look like? I'm already familiar with the usual examples on Stackoverflow.
  • 1
    "*Is Set ( O, P, V, Throw ) equivalent to map.set(k,v)?*" - no, it's the abstract representation of `O[P] = V;` – Bergi Aug 15 '20 at 15:26
  • Note also that `Set()`, the abstract operation, is not the same thing as `[[Set]]`. – Pointy Aug 15 '20 at 15:28
  • "*I looking in the right place for that?*" - yes, but it's the specification an implementation should follow, not the documentation. Docs would be e.g. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse – Bergi Aug 15 '20 at 15:29
  • Doh! That makes sense now. Thanks. – user3186033 Aug 15 '20 at 15:29
  • "*the function is defined in terms of itself.*" - no, you need to distinguish the abstract operation *Set* from the internal method *[[Set]]*, which basically does [dynamic dispatch](https://en.wikipedia.org/wiki/Dynamic_dispatch) on different kinds of objects – Bergi Aug 15 '20 at 15:32
  • The link explicitly states “Set” is an abstract operation. It’s not defined in terms of itself, the actual set operation is the concrete set implementation of O. Re: Q4, not sure what you mean—are you asking if there’s anything in the high-level description that cannot be expressed in JS itself? Why not look at an actual implementation along with the spec? – Dave Newton Aug 15 '20 at 15:37
  • Thanks for your informative posts! I'm embarrassed to admit I'm not exactly sure where I would find a full implementation. I may be lacking the vocabulary to search for it properly. MDN has a few examples of how to call the function, and then links to the spec page I was on. If I had to guess I'd say it'd be most similar to a temp-swap approach. – user3186033 Aug 15 '20 at 16:22

0 Answers0