引用 Object.prototype.toString.call 导致“TypeError: undefined 不是

Reference to Object.prototype.toString.call resulting in 'TypeError: undefined is not a function'

本文关键字:TypeError undefined 不是 导致 Object prototype toString call 引用      更新时间:2024-03-20

我遇到了一个不寻常的情况。我存储了对Object.prototype.toString.call的引用,以尝试进行快捷方式,将其作为赋值变量调用会导致 TypeError,而每次直接调用它则不会。

谁能解释一下实际发生的事情,而不是我相信我正在做的事情?

var toString = Object.prototype.toString.call;
toString({}); //Uncaught TypeError: undefined is not a function

而以下工作:

var toString = Object.prototype.toString;
toString.call({});

非常感谢。

当你在做的时候

var obj = {};
console.log(obj.toString());

toString函数中的thisThisBinding是指obj。换句话说,this = obj.这就是它起作用的原因。该方法toString使用this,而不是参数。

当你执行 var toString = Object.prototype.toString.call; 时,this引用会丢失,这实际上是在方法中操作的。

但在第二种情况下,您只是存储函数引用,并且通过使用 Function.call ,您将this设置为 {} ,这就是它工作的原因,因为this引用设置为要操作的Object

第一种情况是对未绑定Function.call的引用,所以

var unbound_call = Object.prototype.toString.call;
unbound_call({});
// equivalent
Function.prototype.call.call(undefined, {}); // There is no `this`, so undefined
// equivalent
undefined.call({});

当然,这是没有意义的,因为call期望在Function对象上调用,而不仅仅是任何对象。

应该注意的是,Firefox 会告诉您这种不兼容性:

类型错误:函数原型调用不兼容未定义

(好吧,undefined仍然具有误导性(

至于你的第二个版本:

var unbound_toString = Object.prototype.toString.call;
unbound_toString.call({})
// equivalent
Object.prototype.toString.call({}); // D'OH
// equivalent
{}.toString();

所以这是一个合理的呼吁并且有效。