为什么Error对象可以打印纯字符串信息

Why Error object can print pure string message

我不想从 Error 继承或扩展,所以如果您 post 的解决方案是从 post 继承或扩展,请不要将我的问题标记为重复=11=]

下面是我的示例代码和 Chrome 上的 运行。 console.log 下方的评论是 Chrome 开发人员工具控制台选项卡的输出。

我想知道的是为什么Error对象可以输出原始字符串消息,而我的CustomError会输出一个对象。

是否可以实现一个类似Error对象的对象可以输出原始字符串消息

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    function CustomError() {
      this.message = "MyErrorMessage";
    }

    var nativeError = new Error();
    var customError = new CustomError();

    console.log(nativeError);
    // Error

    console.log(customError);
    // CustomError {message: "MyErrorMessage"}

    Error.prototype.message = "Modify native error prototype message";
    var nativeErrorAfterModifyPrototypeMessage = new Error();
    console.log(nativeErrorAfterModifyPrototypeMessage);
    // Error: Modify native error prototype message

    CustomError.prototype.message = "Modify custom error prototype message";
    customErrorAfterModifyPrototypeMessage;
    var customErrorAfterModifyPrototypeMessage = new CustomError();
    console.log(customErrorAfterModifyPrototypeMessage);
    // CustomError {message: "MyErrorMessage"}

    customErrorAfterModifyPrototypeMessage.__proto__.message =
      "Modify custom error prototype message";

    console.log(customErrorAfterModifyPrototypeMessage);
    //index.html:37 CustomError {message: "MyErrorMessage"}
  </script>
</html>

仅仅是因为Error实例被控制台特殊处理,使用.toString()进行格式化。如果你想要这种行为,你必须继承自 Error

开发工具的源代码

来自@Berg评论的回答

您可以随时覆盖 console.log 并自己对 CustomError 进行特殊处理。

function CustomError(message = "") {
    this.message = message;
    //override toString to just return your message (or whatever you want your output to look like)
    this.toString = () => this.message;
}

const ce = new CustomError("some message");

//this shows the builtin behaviour of console.log
console.log(ce);

//preserve the original console.log function, we'll need it later on
console.originalLog = console.log;

//override console.log with a new function
console.log = function() {
    //check if any of the arguments is a CustomError
    //and replace CustomErrors with its string representation
    for (let i = 0; i < arguments.length; i++)
        if (arguments[i] && arguments[i].constructor.name === "CustomError") 
            arguments[i] = arguments[i].toString();

    //call the original log function with the updated arguments
    console.originalLog.apply(this, arguments);
}

//this shows the overriden behaviour of console.log
console.log(ce);

//and back to original behaviour again
console.log = console.originalLog;
console.originalLog = undefined;
console.log(ce);

可能不是最有效或最优雅的解决方案,但它可以在大多数情况下完成工作。如果 CustomError 嵌套在另一个对象或数组中,它将不起作用。

确保在另一个变量中保留 console.log 的原始行为,以便在修改 arguments 后可以使用它。