• 作者:老汪软件技巧
  • 发表时间:2024-10-01 11:03
  • 浏览量:

前言

某J厂二面,面试官给了一道题,说要探测一下我的深♂︎度

我心想:“啊♂︎,完犊子了,我浅的,轻松就到底了。”

// what is the result?
typeof Array.prototype
typeof Function.prototype
typeof Object.prototype

我说:“object,object,null"

面试官笑了,他说:“第一个是object,第三个考察的不是原型链顶端,第二个是function。”

我:“啊?!......”

typeof

面试结束后我去研究了下,正确答案是:

typeof Array.prototype // 'object'
typeof Function.prototype // 'function'
typeof Object.prototype // 'object'

实际上主要考点就是Function.prototype,但得先从typeof 说起。

typeof运算符返回一个字符串,表示运算符后面操作数的类型。

用来判断基础类型,贼拉准(Null除外),Bigint和Symbol都没问题,见下表

类型结果

Undefined

"undefined"

Null

"object"

Boolean

"boolean"

Number

"number"

BigInt

"bigint"

String

"string"

Symbol

"symbol"

Function (class)

"function"

其他任何对象

"object"

typeof null 为啥是“object”?

额,显然这是个bug,俗称历史遗留问题。来看看咋遗留下来的。

翻译下:早期js版本,值32比特存储,有个1-3位用来代表类型,而tag位是000的话,代表对象object。

巧了,Null正好是空指针,其数据就是tag位000与数值位也是0,所以typeof执行的时候,看到tag为是000,所以返回object。

这bug也是神奇,而且还不能修复,一旦修复,之前的代码全乱套了。

typeof NaN 为啥是number?

NaN 代表 "Not-a-Number"(不是一个数字),但它实际存储是一种特殊的数值类型。

NaN 是以特定的位模式存储的浮点数。根据 IEEE 754 标准,一个双精度浮点数由64位组成:1位符号位、11位指数位和52位尾数位。NaN 的特征是其指数部分全为1(即1023,因为指数是偏移过的),并且尾数部分非零。

typeof NaN返回了number,因为typeof内部实现的CPP代码判断它就是number。

使用Number的isNaN方法可以判断出来NaN。

Number.isNaN(NaN) // true

顺便:Infinity与之类似,指数部分也是全为1(即1023),但是尾数部分全部为0。对于-Infinity来说,符号位会被设置为1。

typeof Function.prototype 为啥是function?

function并不是基础类型。可以看做是从object中扣出去的一部分

typeof 返回function的情形有:函数,匿名函数,class类

typeof function () {} === "function";
typeof Function === 'function';

Function 是一个构造函数,所以typeof Function 返回function

构造函数的原型对象通常是一个对象,所以

typeof Array.prototype // 'object'
typeof Object.prototype // 'object'

只有Function.prototype是非常特别的

js[协议]()里面有写

翻译一下就是:它本身是个function 对象,所以typeof返回function

为啥要这么搞呢?绿色的note写了,ES2015的特性。

再看个奇葩的

Function.__proto__ === Function.prototype // true

也就是Function实例的构造函数是Function,我构造了我自己?

这里面肯定还有神奇的设定,就不展开了,因为我也不知道了。

总结