更改从内置数组扩展的对象的控制台日志记录名称

Change console logging name of object extended from built-in Array

我有一个基本的 class 扩展数组,如下所示:

class Vector extends Array {
  constructor(array) {
    // doesn't handle special case of length 1 array
    super(...array);
  }
  // more code
}

即使我尝试更改 nametoString 原型,我仍然将其打印为 Array:

Vector.constructor.prototype.toString = () => "Vector";
new Vector([1,2,3]) // shows Array(3) [ 1, 2, 3 ] in Firefox console

如何让 class 在控制台中显示为 Vector(3) [ 1, 2, 3 ]

我认为使用 V8 引擎的 Edge/Chrome/node 尽量聪明并在控制台中将对象显示为 Vector。你不需要行 Vector.constructor.prototype.toString = () => "Vector"; 来实现,他们无论如何都会显示为 Vector

另一方面,Firefox 似乎在控制台输出中只显示 JS 内置类型。对于简单的 class,它将显示 Object。但是 chrome 将显示 class 名称。

其次,您对JS对象模型的理解不正确。 Vector.constructor 不是第 2 行上的构造函数。但它是构造 Vector class 的构造函数。最后请记住,class 是一个 function,而 JS 中的 function 是第一个 class 个对象。

由于 Vector 是一个 function,它是从 Function 对象创建的。因此:

Vector.constructor === Function
// true

Function 是 JS 中所有函数的构造函数。所以你有效地做的是改变所有功能:

Vector.constructor.prototype.toString = () => "Vector";
// effectively means
// Function.prototype.toString = () => "Vector";

// we can test it
function anyFunction() {}
anyFunction.toString()
// "Vector"

您第 2 行的 constructor 实际上是由 Vector 本身表示的。

Vector.prototype.toString = () => "Vector";
(new Vector([1,2])).toString();
// "Vector"

同样的事情可以通过重写 class 语法来表示:

class Vector extends Array {
  // .. your code...
  toString() {
        return "Vector [" + super.toString() + "]";
  }
}

(new Vector([1,2])).toString()
// "Vector [1,2]"

很遗憾,虽然它不会达到您最初的期望。

要从 console.log 调用 toString,您可以进行一些串联:

let v = new Vector([1,2])
console.log("Variable is " + v)
// "Variable is Vector [1,2]"