简体   繁体   中英

What are "non-existent property values" in ECMA spec for ARRAY:SORT

In an answer for this question (which otherwise I can fully understand/etc), there'a this curious quite:

From the spec, 15.4.4.11 :

Because non-existent property values always compare greater than undefined property values, and undefined always compares greater than any other value, undefined property values always sort to the end of the result, followed by non-existent property values .

I've checked in the latest version available now and it's "note 1" at the end of sort spec, and it's basically the same as it was when that answer from 2011 was written.

Regarding undefined property values always sort to the end of the result, followed by non-existent property values -- how can it be? what are "non-existent property values"(*)? if we write a.foo and a doesn't have such property, we'll get undefined , so how can it be differentiated?

The sort is called either without any parameter, or with a comparer-style function, and in the latter case, it's our function, and we're bound to read the non-existent property and get undefined .. The sort can't inspect the object's keys for us to decide whever an inspected object has a property or not (in contrast to ie certain underscore/lodash helpers where you define a 'path' like ie pluck or get ). I just dont see how we could trigger this "non-existent property values" case at all.

(*) I've found something that looks like a definition of this term here :

A non-existent property is a property that does not exist as an own property on a non-extensible target. (...) If the target is non-extensible and P is non-existent, then all future calls to [[GetOwnProperty]] (P) on the target must describe P as non-existent (ie [[GetOwnProperty]] (P) must return undefined).

This must-describe-as-nonexistent and must-return-undefined seem to support my doubt.

I've also noticed that the pseudo-code for SortIndexedProperties (used to define sort ) actually contains bits like 3.b. Let kPresent be ? HasProperty(obj, Pk). 3.b. Let kPresent be ? HasProperty(obj, Pk). . So maybe that non-existent property part in sort spec meant to cover some case like the array being mutated by the comparer function and certain keys are removed from it?

A non-existent property on an array will be "included" when sorting only if the array is sparse. Here's an example, look at the comments:

 const arr = []; // 0-length array arr[2] = 'foo'; // Turns into 3-length array. Does not have own properties 0 or 1 arr.sort(); console.log(arr[0]); // Sort result includes a value from defined property console.log(arr.hasOwnProperty(1)); // But not from the sparse elements console.log(arr.length); // But the array will have the same length as originally

As you can see, the properties that didn't exist on the original sparse array are "sorted" to the end of the array, and don't exist on the resulting sorted array either, except for the .length of the sorted array. It started out as an array with a length of 3 and only one own-property, and ended up as an array with a length of 3 and only one own-property (but with that own-property at a different index).

if we write a.foo and a doesn't have such property, we'll get undefined, so how can it be differentiated?

It's equivalent to a .hasOwnProperty check:

 const obj1 = {}; const obj2 = { foo: undefined }; console.log(obj1.hasOwnProperty('foo')); console.log(obj2.hasOwnProperty('foo')); const arr1 = ['abc']; const arr2 = [, 'def']; // sparse array console.log(arr1.hasOwnProperty(0)); console.log(arr2.hasOwnProperty(0));

Best approach to all of this - never use sparse arrays to begin with, they're too confusing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM