foo.toString()和Object.prototype.toString.call(foo)有什么区别?

the*_*fog 5 javascript

如果我定义一个函数:

function foo() {
        alert(this.x);
}
Run Code Online (Sandbox Code Playgroud)

我可以通过调用函数toString上的方法来打印函数定义foo.

console.log(foo.toString())
Run Code Online (Sandbox Code Playgroud)

输出:

function foo(){alert(this.x); }

如果我然后跑

console.log(Object.prototype.toString.call(foo))
Run Code Online (Sandbox Code Playgroud)

输出:

"[对象功能]"

令我惊讶的是输出不同.我认为这两种形式是等价的?,即foo函数toString从顶层继承了方法,Object而使用的Object.prototype.toString.call(foo)只是调用toString传递foo函数作为this.
这两种形式的调用有什么区别?

T.J*_*der 4

这两种调用形式有什么区别?

这不仅仅是调用形式的差异,您还调用了完全不同的函数。

即该foo函数toString从顶层继承了该方法Object,并且 usingObject.prototype.toString.call(foo)只是调用toStringfoo函数作为this.

一切都很完美,除了第一点。:-)foo不继承toStringObject.prototype,因为foo是一个函数,并且Function.prototype(继承自Object.prototype重写 toString以赋予其不同的行为。

你可以这样看到:

console.log(foo.toString === Object.prototype.toString); // false
Run Code Online (Sandbox Code Playgroud)

也完全有可能foo拥有自己的toString,覆盖它继承自的Function.prototype,但默认情况下它不会。

因此,仅更改调用的形式,我们会得到这些,它们是等效的:

console.log(foo.toString());
Run Code Online (Sandbox Code Playgroud)

console.log(foo.toString.call(foo));
Run Code Online (Sandbox Code Playgroud)

或者如果我们知道foo不会覆盖 的Function.prototype版本,那么:

console.log(Function.prototype.toString.call(foo));
Run Code Online (Sandbox Code Playgroud)