相信很多朋友们在开发过程中都会用到typeof
去验证码判断一个变量的数据类型,但是你是否真正了解在进行typeof
的过程中,浏览器到底都做了些什么,接下来就让我们研究研究。
谈一谈js
中的数据类型
或许很多小伙伴看到这个问题,脑子里面很自然都会想到,js中数据类型分为基本数据类型
和引用数据类型
。
基本数据类型又包括:
- number 数字
- string 字符串
- boolean 布尔
- null 空对象指针
- undefined 未定义
- symbol 唯一值
- bigint 大数
引用数据类型:object
(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)。
其实在ECMAScript262
中有详细给出数据类型的标准定义:
4.2 ECMAScript Overview
ECMAScript is object-based: basic language and host facilities are provided
by objects, and an ECMAScript program is a cluster of communicating objects.
In ECMAScript, an object is a collection of zero or more properties each with
attributes that determine how each property can be used—for example, when the
Writable attribute for a property is set to false, any attempt by executed
ECMAScript code to assign a different value to the property fails. Properties are
containers that hold other objects, primitive values, or functions.
A primitive value is a member of one of the following built-in types: Undefined,
Null, Boolean, Number, String, and Symbol; an object is a member of the built-in
type Object; and a function is a callable object. A function that is associated
with an object via a property is called a method.
ECMAScript是基于对象的:基本语言和主机设施是由对象提供的,而ECMAScript程序是通信对象的集群。
在ECMAScript中,对象是0个或多个属性的集合,每个属性都具有决定如何使用每个属性的属性——例如,
当属性的可写属性被设置为false时,执行ECMAScript代码为属性分配不同值的任何尝试都将失败。
属性是容纳其他对象、基本值或函数的容器。原始值是以下内置类型之一的成员:
未定义、Null、布尔、数字、字符串和符号;对象是内置类型对象的成员;
函数是可调用对象。通过属性与对象关联的函数称为方法。
ECMAScript defines a collection of built-in objects that round out the
definition of ECMAScript entities. These built-in objects include the global object;
objects that are fundamental to the runtime semantics of the language
including Object, Function, Boolean, Symbol, and various Error objects; objects
that represent and manipulate numeric values including Math, Number, and Date;
the text processing objects String and RegExp; objects that are indexed
collections of values including Array and nine different kinds of Typed Arrays
whose elements all have a specific numeric data representation; keyed collections
including Map and Set objects; objects supporting structured data including the
JSON object, ArrayBuffer, and DataView; objects supporting control abstractions
including generator functions and Promise objects; and, reflection objects
including Proxy and Reflect.
ECMAScript定义了一个内置对象集合,它完善了ECMAScript实体的定义。这些内置对象包括全局对
象;对象是语言运行时语义的基础,包括对象、函数、布尔值、符号和各种错误对象;表示和操作数值
(包括数学、数字和日期)的对象;文本处理对象字符串和RegExp;对象,该对象是值的索引集合,包括
数组和9种不同类型的数组,其元素都具有特定的数值数据表示;键控集合,包括Map和Set对象;支持
结构化数据的对象,包括JSON对象、ArrayBuffer和DataView;支持控制抽象的对象,包括生成器函
数和承诺对象;以及反射对象,包括代理和反射
我希望小伙伴们可以认真阅读以上文字,有利于加深我们的理解,总结一下:
js中的数据类型分为`原始值类型`和`对象类型`:
`原始值类型`也就是我们刚才所说的`基本数据类型`或者叫`值类型`,具体不一一列出来,请看上文
`对象类型「引用数据类型」`分为:
`标准普通对象`:object
`标准特殊对象`:Array、RegExp、Date、Math、Error……
`非标准特殊对象`:Number、String、Boolean……
`可调用/执行对象「函数」`:function
typeof
的使用
让我们看看typeof
的具体使用方法:
'原始值类型'
typeof 1 // "number"
typeof "" // "string"
typeof true // "boolean"
typeof null // "object"
typeof a // a未被声明定义,因此为"undefined"
typeof Symbol(1) // "symbol"
typeof 12n // "bigint"
'对象类型'
typeof function(){} // "function"
typeof 除可调用/执行对象(函数)的其他对象类型 // "object"
总结一下typeof
的注意点
1、typeof
首先返回的是一个字符串(双引号""包括);
2、原始数据类型中null
的typeof
返回的是"object"
;
3、对象类型中,除了可调用/执行对象的typeof
值为"function"
,其他的都无法通过typeof
进行区分,都为"object"
;
4、typeof
一个未被声明的变量,返回一个"undefined"
。
typeof
的底层原理
12.5.6.1 Runtime Semantics: Evaluation
UnaryExpression : typeof UnaryExpression
Let val be the result of evaluating UnaryExpression.
If Type(val) is Reference, then
If IsUnresolvableReference(val) is true, return “undefined”.
Let val be GetValue(val).
ReturnIfAbrupt(val).
Return a String according to Table 35.
UnaryExpression: UnaryExpression的类型
设val为对UnaryExpression求值的结果。
如果类型(val)是引用,则
如果IsUnresolvableReference(val)为真,则返回“undefined”。
让val为GetValue(val)。
ReturnIfAbrupt (val)。
根据下表返回一个字符串。
在GetValue(val)
中,计算机底层又进行了处理,它将所有的值都以64位二进制
进行了存储,而typeof
就是按照计算机底层存储的二进制进行检测,它具有效率高的这么一个优点。
检测规则
typeof
会以二进制数开头的某几位进行检测,规则如下:
- 000 对象
- 1 整数
- 010 浮点数
- 100 字符串
- 110 布尔
- 000000… null(全都为0)
- -2^30 undefined
- ……
其中:
1、整数
和浮点数
他们的检测结果返回的都是"number"
数据类型;
2、如果检测到该值二进制开头是以"000"
开头,并且内部实现了call()
方法,则该值为一个"function"
类型。
总结
以上就是有关计算机typeof
检测数据类型的底层原理,这时候可能又有小伙伴问了,那如何去检测对象类型中的除可调用对象的其他三种对象类型呢?后续还会对这一块进行讲解,请大家持续关注哦。码字不易,感谢大家的阅读。转载请附上原文链接,谢谢啦^_^。