在这个问题的答案中(否则我可以完全理解/等),有这样一个相当奇怪的:
来自规范,15.4.4.11:
因为不存在属性值总是比较大于未定义的属性值,且未定义总是比较大于任何其他值,未定义的属性值总是排序到末尾结果后面跟着不存在的属性值.
我检查了目前可用的最新版本,它是"注1"在sort
规范的末尾,它与2011年的答案基本相同。
关于undefined property values always sort to the end of the result, followed by non-existent property values
——它怎么可能是?什么是"不存在的属性值"(*)?如果我们写a.foo
和a
没有这样的性质,我们就得到undefined
,那怎么微分呢?
调用sort
时要么不带任何参数,要么带比较器风格的函数,在后一种情况下,它是我们的函数,我们必须读取不存在的属性并获得undefined
..sort
不能检查对象的键,让我们决定被检查的对象是否有属性(与某些下划线/lodash helper相反,你定义了一个"路径",如pluck
或get
)。我只是不明白如何触发这个"不存在的属性值"。
(*)我在这里找到了一个类似于这个术语的定义:
不存在的属性是指在非可扩展目标上不作为自身属性存在的属性。(…(如果目标不可扩展且P不存在,则所有未来对目标上的[[GetOwnProperty]] (P)的调用必须将P描述为不存在(即[[GetOwnProperty]] (P)必须返回undefined)。
这个"必须描述为不存在"one_answers"必须返回为未定义"似乎支持了我的怀疑。
我还注意到SortIndexedProperties
的伪代码(用于定义sort
)实际上包含像3.b. Let kPresent be ? HasProperty(obj, Pk).
这样的位。所以也许sort
规范中的non-existent property
部分意味着涵盖某些情况,如比较器函数对数组进行变异,并从中删除某些键?
数组中不存在的属性将被" include ";仅在数组稀疏的情况下排序时。下面是一个例子,看看注释:
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
可以看到,原始稀疏数组中不存在的属性被"sorted"到数组的末尾,并且除了已排序数组的.length
之外,也不存在于结果排序数组中。它开始是一个长度为3且只有一个own-property的数组,最后变成了一个长度为3且只有一个own-property的数组(但是这个own-property在不同的索引上)。
如果我们写a。foo而a没有这样的属性,我们会得到undefined,那么如何区分它呢?
相当于.hasOwnProperty
检查:
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));
解决这一切的最佳方法——从一开始就不要使用稀疏数组,它们太令人困惑了。