JavaScript编程中,比较运算、数据转换操作等是十分常见,不过,计算机是如何工作、如何判断的,可能大部分人都不了解,想要学好 JS 这门弱类型语言,搞懂其类型判断机制很有必要,这里将从一次比较运算说起。
你了解比较运算 x == y,Js 是如何去判断的吗?
11.9.3 规定的 abstract equality comparison 机制
几个简单例子,看有木有一个初步的了解。
Tips:粘贴到 chrome devtool 的 snippets 里,再 run 一下就知道结果了。
1 | console.log('undefined == null', undefined == null); |
基本数据类型(划重点了)
primitives 类型有 6 种:
- boolean
- number (Infinity, NaN)
- string
- null
- undefined
- symbol (ECMAScript 6 新增)
object 类型
目前,js只有以上7种类型,其中原始类型的值是 freezed 。即变量被赋予不同的原始值,只是将其指向了内存中的另外一个原始值,但原本的那个原始值在内存中并没有变化。 Object类型则不同,对象内部属性被赋予不同值后,在内存中表示该对象的一些字节确实被改变了。
装箱与拆箱
为了便于操作基本类型值,ECMAScript提供了3个特殊的引用类 Boolean, Number, String,每当读取一个基本类型值时,就会创建一个对应的基本包装类型对象,以便调用一些方法操作这些数据。
1 | // |
1 | // 当上方代码创建变量 s 后,后台会创建 String 类型的一个实例,将 s 包装成一个值为 "stringtest" 的 String 对象,这就是自动装箱操作。 |
1 | // 在实例 s 调用 String 对象的方法后,后台会销毁这个实例,s 的值被指向基本数据类型 "test",这就是自动拆箱。 |
1 | // 通过 typeof 查询基本数据类型 |
两个类型转换常用函数
- valueOf() 返回这个对象逻辑上对应的原始类型的值。
比如说,String 包装对象的 valueOf(),应该返回这个对象所包装的字符串。 - toString() 返回这个对象的字符串表示。
即用一个字符串来描述这个对象的内容。
valueOf() 和 toString() 是定义在 Object.prototype 上的方法,但是 js 的许多内置对象都重写了这两个函数,以符合自身需求。
JS 内部用于实现类型转换的4个函数
ToPrimitive ( input [ , PreferredType ] )
将input转化成一个原始类型的值。 PreferredType参数要么不传入,要么是 Number 或 String。
如果 PreferredType 参数是 Number,ToPrimitive这样执行:
- 如果input本身就是原始类型,直接返回input。
- 调用input.valueOf(),如果结果是原始类型,则返回这个结果。
- 调用input.toString(),如果结果是原始类型,则返回这个结果。
- 抛出TypeError异常。
以下是 PreferredType 不为 Number 时的执行顺序。
- 如果PreferredType参数是String,则交换第2和第3步的顺序,其他执行过程相同。
- 如果PreferredType参数没有传入
- 如果input是内置的Date类型,PreferredType 视为String
- 否则PreferredType 视为 Number
可以看出,ToPrimitive依赖于 valueOf 和 toString 的实现。
ToBoolean ( argument )
ToNumber ( argument )
ToString ( argument )