如何理解Object.prototype.toString.call(obj)

被面试官问
为什么先toString后call
call在这里的作用是什么
(一般call是绑定this,面试官说的意思好像是call这里不是绑定的意思,问我call在这里的作用是什么)

阅读 2.6k
3 个回答

先说这个代码的作用,是获取obj的类型的。
然后说一下为什么这样写:

  1. 为什么不直接调用obj.toString(),这是因为各种类型都会对toString的重新实现,比如:

    var obj = 3;
    obj.toString(); // 3
    
    obj = {};
    obj.toString(); // [object Object]
    
    obj = [1];
    obj.toString(); // 1
    
    obj = null;
    obj.toString; // 直接报错

    所以,无法直接调用toString来判断类型。

  2. 那为什么不用typeof?我们再看typeof的效果:

    typeof null; // object
    typeof undefined; // undefined
    typeof []; // object
    typeof {}; // object
    typeof 0; // number
    typeof new Date(); // object

    可以看到,null[]new Date(){}根本无法区分。

  3. 再说Object.prototype.toString这个方法,这个是在Object原型链上的方法,就是最原始的那个实现,不会被obj的实现所影响,也不会因为obj的值而报异常,再来看看效果:

    // 不想写太多,变短一点
    const toString = Object.prototype.toString;
    
    toString.call(null); // [object Null]
    toString.call(undefined); // [object Undefined]
    toString.call({}); // [object Object]
    toString.call(0); // [object Number]
    toString.call(""); // [object String]
    toString.call([]); // [object Array]
    toString.call(new Date()); // [object Date]

    可以看出,这个方法可以真实反映obj的具体类型。

所以,这里虽然使用了call,但是考查点却跟call没有关系。call的作用就是让obj能够调用Object原型链上的toString方法。

Object.prototype.toString 是一个函数,call是函数对象上的一个方法。Func.call(null,a,b,c).函数使用call方法一般有两个作用,一是指定这个函数的this指向(call的第一个参数),二是传递参数(a,b,c)

拆开看,Object.prototype.toString 这是一个 Function 对象,而 Function 对象原型链上又有 Function.prototype.call

如果 Function.prototype.call(与之一同常出现的还有 Function.prototype.apply)是干啥的你都不清楚的话,再多学习学习吧,百度一下 JS 中 call/apply 大把结果。

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