问答

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

作者:admin 2021-08-12 我要评论

如题,demo如下 const obj = { valueOf() { return 'valueOf被调用了' }, toString() { return 'toString被调用了' }}console.log(obj.toString()); // "toStrin...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

如题,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调用也能获得预期结果。真的是很困扰,求大佬解答

###

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

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 指向问题深度解析

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 类型判断Object.prototypr.toString.ca

    类型判断Object.prototypr.toString.ca

  • 什么是分布式任务调度?

    什么是分布式任务调度?

  • vue项目,修改后保存,编译太慢如何解

    vue项目,修改后保存,编译太慢如何解

  • javascript如何处理这段字符串?

    javascript如何处理这段字符串?

腾讯云代理商
海外云服务器