类型判断Object.prototypr.toString.call()为什么要加call呢?

如题,demo如下

const obj = {
    valueOf() {
        return 'valueOf被调用了'
    },
    toString() {
        return 'toString被调用了'
    }
}

console.log(obj.toString()); // "toString被调用了"
console.log(Object.prototype.toString(obj)); // "[object Object]"
console.log(Object.prototype.toString.call(obj)); // "[object Object]"

在这个demo中,不加call调用也能获得预期结果。真的是很困扰,求大佬解答

阅读 6k
5 个回答

你传一个数字就可以看到差别

Object.prototype.toString(1) // [object Object]
Object.prototype.toString.call(1) // [object Number]

这是 MDN 的描述:

每个对象都有一个toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString()方法被每个Object对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object _type_]",其中type是对象的类型。

Object.prototype 也是一个对象,Object.prototype.toString 调用的是 Object.prototype 这个对象的 toString 方法,所以永远是 "[object Object]"

而以 Object.prototype.toString.call 的形式调用,是调用 Object.prototype.toString 这个函数调用且函数内部的 this 执行 call 方法传递的第一个参数。

不同就在于 this 指向。

call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果

Object.prototype.toString.call(1)
"[object Number]"

Object.prototype.toString.call(NaN);
"[object Number]"

Object.prototype.toString.call("1");
"[object String]"

Object.prototype.toString.call(true)
"[object Boolean]"

Object.prototype.toString.call(null)
"[object Null]"

Object.prototype.toString.call(undefined)
"[object Undefined]"

Object.prototype.toString.call(function a() {});
"[object Function]"

Object.prototype.toString.call([]);
"[object Array]"

Object.prototype.toString.call({});
"[object Object]"

你第二种写法根本就是错误的,和 obj 压根就没关系,不信你试试,传啥都是这个输出。

Object.prototype.toString(1); // "[object Object]"
Object.prototype.toString(true); // "[object Object]"
Object.prototype.toString('hello world'); // "[object Object]"

Object.prototype.toString ( )这个方法是不接受参数的,
所以这种形式的调用Object.prototype.toString(obj) 传入的obj根本不会用。

大致看看,下面两个版本的规范:
https://www.ecma-internationa...
https://www.ecma-internationa...

都是在通过判断内部的this value,决定返回值,类似"[object", tag, and "]"

刚好call方法,可以通过传入参数,改变函数运行时使用的 this 值,从而实现类型判断。

看看这个示例,不知道能不能明白一点:

function test(obj) {
    console.log("----------------------------");
    console.log(`this is ${this}`);
    console.log(`parameter is ${obj}`);
}

test("hello");
test.call("hello");

上面代码的运行结果:

----------------------------
this is [object global]
parameter is hello
----------------------------
this is hello
parameter is undefined

推荐阅读:JavaScript 的 this 指向问题深度解析

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题