前端知识点---一行代码检测数据类型(javascript)

typeof 只能检测基本数据类型和函数, instanceof不能检测基本数据类型

如何一句话检测数据类型呢?

function _typeof(value) {
    return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}

结果是一个全为小写的字符串

下面来一步一步分析这段代码 :

原型链解析

Object 是原型链中最上层的构造函数,但 Object.prototype 才是原型链的顶端。

在 JavaScript 中,所有对象最终都继承自 Object.prototype,但 Object 作为构造函数,也有自己的原型关系

  1. Object 是构造函数
console.log(typeof Object); // "function"

它本质上是一个函数,用于创建对象。

  1. Object.prototype 是原型链的顶端
console.log(Object.prototype.__proto__); // null 注意__proto__前后都是两个下划线 

Object.prototype 没有再往上的 proto,因此它是原型链的最顶层。

  1. Object 作为一个函数,也有自己的原型
console.log(Object.__proto__ === Function.prototype); // true

Object 作为函数,继承自 Function.prototype。
这意味着 所有构造函数(包括 Object 自己)最终都继承自 Function.prototype。

toString

Object.prototype.toString():将对象转换为字符串,通常是将对象的类型表示为 [object Type]

  • 第一个 “object” → 固定前缀,表示这个值是一个对象(所有对象都会有这个前缀)。
  • 第二个 “Object” → 对象的具体类型,

如果是没有加Object.prototype 那toString的结果只是一个字符串

console.log(Object.prototype.toString.call(123));       // "[object Number]"
console.log(Object.prototype.toString.call("hello"));  // "[object String]"
console.log(Object.prototype.toString.call(true));     // "[object Boolean]"
console.log(Object.prototype.toString.call([]));       // "[object Array]"
console.log(Object.prototype.toString.call({}));       // "[object Object]"
console.log(Object.prototype.toString.call(null));     // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(function(){})); // "[object Function]"
console.log(Object.prototype.toString.call(new Date()));   // "[object Date]"

call方法

如果没有call方法
看下面这段代码:

let string1 = "hello";
console.log(Object.prototype.toString(string1)); 
// ❌ 报错:TypeError: this is not a function or its prototype chain

实际上等价于:

Object.prototype.toString.call(undefined); // ❌ TypeError

因为 toString() 需要一个明确的 this 绑定,但你直接调用 Object.prototype.toString(value),没有指定 this,默认会把 this 绑定到 Object.prototype,导致错误。

如果 string1 是一个对象:

let string1 = new String("hello");
console.log(Object.prototype.toString(string1)); // "[object Object]"

.call(value) 手动指定 this 指向 value,这样 toString() 方法会正确地检查 value 的 [[Class]],然后返回 “[object Type]”。

slice(8, -1)

现在,我们已经知道 Object.prototype.toString.call(value) 返回的字符串形态是 “[object Type]”。

slice(8, -1) 的作用是 去除 [object 和 ],只留下 Type。

拆解 slice(8, -1)
假设 value = [],那么:

let str = Object.prototype.toString.call([]);
console.log(str); // "[object Array]"

📌 “Array” 这个部分从哪里开始?

"[object " 共有 8 个字符(索引 0~7),所以 索引 8 是 A(Array)。
“]” 在末尾,我们用 -1 让它被去掉。
效果如下:

let type = str.slice(8, -1); // 取索引 8 开始,到倒数第 2 个字符结束
console.log(type); // "Array"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值