Skip to content
扫码开始移动端阅读

猜想

首先猜一下以下的运行结果

js
JSON.stringify(new Error('111'))

然后再猜一下以下的运行结果

js
JSON.stringify(new TypeError('222'))

结果

js
JSON.stringify(new Error('111')) // "{}"
JSON.stringify(new TypeError('222')) // "{}"

刨根问底

深挖JSON.stringify

为什么会这样呢?我们先看一下知名网站墨大奈(MDN)JSON.stringify的定义

JSON.stringify

JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。

好像没刨到,再深挖一下

更详细的描述

  1. JSON.stringify()将值转换为相应的 JSON 格式
  2. 转换值如果有 toJSON() 方法,该方法定义什么值将被序列化
  3. 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中
  4. 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值
  5. undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined).
  6. 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。
  7. 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
  8. Date 日期调用了 toJSON() 将其转换为了 string 字符串(同 Date.toISOString()),因此会被当做字符串处理。
  9. NaN 和 Infinity 格式的数值及 null 都会被当做 null。
  10. 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。

找到了,是因为:其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性

深挖Error对象


常用的Error对象有以下几种

EvalError 通过 eval() 创建的错误会被抛出 EvalError 对象。
RangeError 数值变量或参数超出其有效范围时抛出 RangeError 对象。
ReferenceError 无效引用时抛出 ReferenceError 对象。
SyntaxError 语法错误时抛出 SyntaxError 对象。
TypeError 变量或参数不属于有效类型时抛出 TypeError 对象。
URIError URI 相关函数的参数不正确时抛出 URIError 对象。
AggregateError 用于表示聚合错误,它是 Error 的子类,用于将单个错误与多个错误相关联。
InternalError 表示 JavaScript 引擎内部错误。当 JavaScript 引擎遇到意料之外的情况时,会抛出 InternalError。
Error 创建一个错误对象。当 JavaScript 引擎遇到运行时错误(runtime errors)时,会抛出一个错误对象。Error 对象也可用于用户自定义的异常的基础对象。

Error对象的属性

Error.prototype.constructor 指向创建了该对象的函数。
Error.prototype.message 错误信息。
Error.prototype.name 错误名称。
Error.prototype.stack 一个字符串,描述了代码中 Error 被实例化的位置。

Error对象的方法

Error.prototype.toString() 返回一个表示该对象的字符串。
Error.stackTraceLimit() 设置或返回堆栈跟踪的最大数量。
Error.captureStackTrace() 创建一个错误对象并包含堆栈跟踪,而不是在当前位置创建。
Error.prepareStackTrace()`` 格式化堆栈跟踪,以便它可以用作 toString() 方法的一部分。

结论

如果我们需要打印字符串的结果,应该使用new Error().toString(),而不是JSON.stringify(new Error())。
不得不感慨一下,不愧是严谨的JavaScript,让我们不知不觉又学到一个知识点。