Object.prototype.toString.call检测数据类型

1. 为什么可以检测数据类型

我们知道typeof可以检测数据类型,但是是不准确的,比如

typeof null // object
typeof [] // object

想更准备的检测数据类型可以用Object.prototype.toString.call,但是为什么该方法可以检测数据类型,变量自带的toString函数为什么不能检测呢?

910389-2939abaad2b92a50.png
测试

a b c d 并没有得到 "[object type]"这种形式,为什么会这样,因为构造他们的函数的prototype重写了toString函数,为什么number string boolean 也有toString方法,因为他们的包装函数的prototype是有这些方法的,在number string boolean 执行的时候会进行装箱操作,使其具备一些函数,执行完这些包装函数会被销毁。为什么null和undefined会报错,因为他们没有对应的包装函数,不会进行装箱操作。
为什么用Object.prototype.toString.call(obj)检测对象类型?

2. 第二种写法

【进阶 6-2 期】深入高阶函数应用之柯里化提到可以使用const toStr = Function.prototype.call.bind(Object.prototype.toString);返回改造后的toString方法,然后可以直接使用该方法

910389-a3ac3cecc1b17817.png
改造后的toString

看到这里就有中似曾相识的感觉,将类数组转为数组有的办法是常见的办法是:

function list() {
  return Array.prototype.slice.call(arguments);
}

但是MDN Array​.prototype​.slice()给出了另一种办法

var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);

function list() {
  return slice(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

JavaScript 深入之类数组对象与 arguments

对比两种写法,以及木易杨说的解释,加上自己的测试

910389-a4c5a44e8576fb7a.png
image.png

call 的作用是绑定函数的上下文对象this,但是我上面直接这么操作,并没有用函数去调用call,所以tt是undefined。那么 Function.prototype.call肯定需要个函数去调用它,不能直接 Function.prototype.call,所以需要个bind函数去绑定 Function.prototype.call所需要的调用函数,比如 Function.prototype.call.bind(Object.prototype.toString)这样就指定了 Function.prototype.call的调用者是 Object.prototype.toString,也就是绑定了 Function.prototype.call的上下文对象this为 Object.prototype.toStringFunction.prototype.call.bind(Object.prototype.toString)返回的是绑定了上下文对象this的call函数。

猜你喜欢

转载自blog.csdn.net/weixin_33804582/article/details/90846798