此更新修复了字符 U+D800 到 U+DFFF 的处理,有时可以进入 JSON 字符串。 这可能是一个问题,因为 JSON.stringify 可能会将这些数字格式化为没有等效 UTF-8 字符的值, 但 JSON 格式需要 UTF-8 编码。
解析方法使用格式良好的JSON字符串,如:
'{ “prop1” : 1, "prop2" : 2 }'; // A well-formed JSON format string
注意,要创建正确 JSON 格式的字符串,绝对需要在属性名周围加上双引号。缺少或任何其他类型的引号都不会生成格式良好的JSON。
'{ “prop1” : 1, "meth" : () => {}}'; // Not JSON format string
JSON 字符串格式与 Object Literal 不同,后者看起来几乎一样,但可以使用任何类型的引号括住属性名,也可以包含方法(JSON格式不允许使用方法):
let object_literal = { property: 1, meth: () => {} };
不管怎样,一切似乎都很好。第一个示例看起来是兼容的。但它们也是简单的例子,大多数情况下都能顺利地工作!
U+2028 和 U+2029 字符
问题是, ES10 之前的 EcmaScript 实际上并不完全支持 JSON 格式。前 ES10 时代不接受未转义行分隔符 U+2028 和段落分隔符 U+2029 字符:
对于 U+D800 - U+DFFF 之间的所有字符也是如此
如果这些字符潜入 JSON 格式的字符串(假设来自数据库记录),你可能会花费数小时试图弄清楚为什么程序的其余部分会产生解析错误。
因此,如果你传递 eval 这样的字符串 “console.log(' hello ')”,它将执行 JavaScript语句 (通过尝试将字符串转换为实际代码),也类似于 JSON.parse 将处理你的 JSON 字符串的方式。
稳定的 Array.prototype.sort()
V8 之前的实现对包含10个以上项的数组使用了一种不稳定的快速排序算法。
一个稳定的排序算法是当两个键值相等的对象在排序后的输出中出现的顺序与在未排序的输入中出现的顺序相同时。但情况不再是这样了,ES10 提供了一个稳定的数组排序:
var fruit = [ { name: "Apple", count: 13, }, { name: "Pear", count: 12, }, { name: "Banana", count: 12, }, { name: "Strawberry", count: 11, }, { name: "Cherry", count: 11, }, { name: "Blackberry", count: 10, }, { name: "Pineapple", count: 10, } ]; // 创建排序函数: let my_sort = (a, b) => a.count - b.count; // 执行稳定的ES10排序: let sorted = fruit.sort(my_sort); console.log(sorted);
控制台输出(项目以相反的顺序出现):
新的Function.toString()
函数是对象,并且每个对象都有一个 .toString() 方法,因为它最初存在于Object.prototype.toString() 上。 所有对象(包括函数)都是通过基于原型的类继承从它继承的。
这意味着我们以前已经有 funcion.toString() 方法了。
但是 ES10 进一步尝试标准化所有对象和内置函数的字符串表示。 以下是各种新案例:
典型的例子:
function () { console.log('Hello there.'); }.toString();
控制台输出(函数体的字符串格式:)
⇨ function () { console.log('Hello there.'); }
下面是剩下的例子:
直接在方法名 .toString()
Number.parseInt.toString(); ⇨ function parseInt() { [native code] }
绑定上下文:
function () { }.bind(0).toString(); ⇨ function () { [native code] }
内置可调用函数对象:
Symbol.toString(); ⇨ function Symbol() { [native code] }
动态生成的函数:
function* () { }.toString(); ⇨ function* () { }
prototype.toString
Function.prototype.toString.call({}); ⇨ Function.prototype.toString requires that 'this' be a Function"
可选的 Catch Binding
在过去,try/catch 语句中的 catch 语句需要一个变量。 try/catch 语句帮助捕获终端级别的错误:
try { // Call a non-existing function undefined_Function undefined_Function("I'm trying"); } catch(error) { // Display the error if statements inside try above fail console.log( error ); // undefined_Function is undefined }
在某些情况下,所需的错误变量是未使用的:
try { JSON.parse(text); // <--- this will fail with "text not defined" return true; <--- exit without error even if there is one } catch (redundant_sometmes) <--- this makes error variable redundant { return false; }
编写此代码的人通过尝试强制 true 退出 try 子句。但是,这并不是实际发生的情况
(() => { try { JSON.parse(text) return true } catch(err) { return false } })() => false
在 ES10 中,捕获错误的变量是可选的
现在可以跳过错误变量:
try { JSON.parse(text); return true; } catch { return false; }
目前还无法测试上一个示例中的 try 语句的结果,但一旦它出来,我将更新这部分。
标准化 globalThis 对象
这在ES10之前, globalThis 还没有标准化。
在产品代码中,你可以自己编写这个怪物,在多个平台上“标准化”它: