为什么不将“9007199254740991”视为整数索引?
Why is not "9007199254740991" treated as an integer index?
根据 the specification,数值为 2 ** 53 - 1
的字符串值 属性 键必须被视为整数索引。
根据 the specification,[[OwnPropertyKeys]]
内部方法必须枚举 属性 键,这是一个整数索引,按数字升序排列。
根据the specification,Reflect.ownKeys
调用[[OwnPropertyKeys]]
内部方法。
所以,如果我的理解是正确的,下面的代码应该按数字升序显示 属性 键(即 ["9007199254740990", "9007199254740991"]
)。
然而,所有现有的实现都以 属性 创建的升序时间顺序显示 属性 键(即 ["9007199254740991", "9007199254740990"]
)。
console.log(Reflect.ownKeys({"9007199254740991": null, "9007199254740990": null}));
我的错误是什么?
9007199254740991
是JavaScript中的最大安全整数。
var x = Number.MAX_SAFE_INTEGER + 1,
y = Number.MAX_SAFE_INTEGER + 2,
z = Number.MAX_SAFE_INTEGER + 3,
i = Number.MAX_SAFE_INTEGER + 4,
j = Number.MAX_SAFE_INTEGER + 5;
console.log("max: "+Number.MAX_SAFE_INTEGER);
// expected output: 9007199254740991
// real output: 9007199254740991
console.log("x: "+x);
// expected output: 9007199254740992
// real output: 9007199254740992
console.log("y: "+y);
// expected output: 9007199254740993
// real output: 9007199254740992
console.log("z: "+z);
// expected output: 9007199254740994
// real output: 9007199254740994
console.log("i: "+i);
// expected output: 9007199254740995
// real output: 9007199254740996
console.log("j: "+j);
// expected output: 9007199254740996
// real output: 9007199254740996
有些行为符合预期。
阅读以下内容:
- MDN web docs > Number.MAX_SAFE_INTEGER
- What is JavaScript's highest integer value that a number can go to without losing precision?
所以我们知道:
bitwise operators and shift operators operate on 32-bit ints, so in that case, the max safe integer is 231-1, or 2147483647.
我不知道 Reflect.ownKeys()
如何将索引按数字顺序排序。
由于以下代码段:
const objs = [
// does not work
{
9007199254740991: null,
9007199254740990: null,
},
// works
{
2147483648: null,
// max save bitwise number
2147483647: null,
},
// works
{
4294967295: null,
// max save bitwise number times 2
4294967294: null,
},
// does not work
{
5368709118: null,
// max save bitwise number times 2.5
5368709117: null,
}
];
const objkeys = [],
max = objs.length;
for (let i = 0; i < max; i++) {
objkeys.push(Reflect.ownKeys(objs[i]))
}
for (let i = 0; i < max; i++) {
console.log(objkeys[i][0]+" < "+objkeys[i][1]);
}
我希望你对 9007199254740991 和 JavaScript
有所了解
The specification of the [[OwnPropertyKeys]]
internal method in ECMAScript 2017 (and in 2018) did not match the real behavior of all major JavaScript engines, so in ECMAScript 2019, the specification has been fixed。
参见 the discussion on GitHub。
根据 the specification,数值为 2 ** 53 - 1
的字符串值 属性 键必须被视为整数索引。
根据 the specification,[[OwnPropertyKeys]]
内部方法必须枚举 属性 键,这是一个整数索引,按数字升序排列。
根据the specification,Reflect.ownKeys
调用[[OwnPropertyKeys]]
内部方法。
所以,如果我的理解是正确的,下面的代码应该按数字升序显示 属性 键(即 ["9007199254740990", "9007199254740991"]
)。
然而,所有现有的实现都以 属性 创建的升序时间顺序显示 属性 键(即 ["9007199254740991", "9007199254740990"]
)。
console.log(Reflect.ownKeys({"9007199254740991": null, "9007199254740990": null}));
我的错误是什么?
9007199254740991
是JavaScript中的最大安全整数。
var x = Number.MAX_SAFE_INTEGER + 1,
y = Number.MAX_SAFE_INTEGER + 2,
z = Number.MAX_SAFE_INTEGER + 3,
i = Number.MAX_SAFE_INTEGER + 4,
j = Number.MAX_SAFE_INTEGER + 5;
console.log("max: "+Number.MAX_SAFE_INTEGER);
// expected output: 9007199254740991
// real output: 9007199254740991
console.log("x: "+x);
// expected output: 9007199254740992
// real output: 9007199254740992
console.log("y: "+y);
// expected output: 9007199254740993
// real output: 9007199254740992
console.log("z: "+z);
// expected output: 9007199254740994
// real output: 9007199254740994
console.log("i: "+i);
// expected output: 9007199254740995
// real output: 9007199254740996
console.log("j: "+j);
// expected output: 9007199254740996
// real output: 9007199254740996
有些行为符合预期。
阅读以下内容:
- MDN web docs > Number.MAX_SAFE_INTEGER
- What is JavaScript's highest integer value that a number can go to without losing precision?
所以我们知道:
bitwise operators and shift operators operate on 32-bit ints, so in that case, the max safe integer is 231-1, or 2147483647.
我不知道 Reflect.ownKeys()
如何将索引按数字顺序排序。
由于以下代码段:
const objs = [
// does not work
{
9007199254740991: null,
9007199254740990: null,
},
// works
{
2147483648: null,
// max save bitwise number
2147483647: null,
},
// works
{
4294967295: null,
// max save bitwise number times 2
4294967294: null,
},
// does not work
{
5368709118: null,
// max save bitwise number times 2.5
5368709117: null,
}
];
const objkeys = [],
max = objs.length;
for (let i = 0; i < max; i++) {
objkeys.push(Reflect.ownKeys(objs[i]))
}
for (let i = 0; i < max; i++) {
console.log(objkeys[i][0]+" < "+objkeys[i][1]);
}
我希望你对 9007199254740991 和 JavaScript
有所了解The specification of the [[OwnPropertyKeys]]
internal method in ECMAScript 2017 (and in 2018) did not match the real behavior of all major JavaScript engines, so in ECMAScript 2019, the specification has been fixed。
参见 the discussion on GitHub。