JavaScript - 数据类型及隐式转换
数据类型
基础数据类型: undefined, null, Number, String, Boolean, Symbol (ES6+)
引用数据类型: Object(Object, Array, Date, RegExp, Function)
基础数据类型 值直接存储在相应 栈内存 上的, 使用时是按值访问;
引用数据类型 地址存储在 占内存上, 内容存储在 堆内存上, 使用时是按 引用访问;
注:
Number, Boolean, String 三种类型 也可以通过 new 关键字创建对应的 基本包装类型, 包装类型的实例
隐式转换
涉及到隐式转换的运算符最多的是 + 和 ==, -*/等运算符只会针对 number 类型, 结果也只转换为 number 类型;
- 将值转换为原始值 ToPrimitive()
- 将值转换为数字 ToNumber();
- 将值转化为字符串 ToString();
ToPrimitive(input, PreferredType?)
input是要转换的值,PreferredType是可选参数,可以是Number或String类型, 只是一个转换标志,转化后的结果并不一定是这个参数所值的类型,但是转换结果一定是一个原始值(或者报错), 也就是说设置 Number 时也可能转换为 string, 设置为 String 时 也可能转化为 Number;
当 PreferredType 未设置时, 按照下面规则设置:
- input 是 Date 类型时, PreferredType = String;
- 否则, PreferredType = Number;
PreferredType = Number:
- input 是原始值, 返回原始值;
- input 不是原始值, 调用 input.valueOf(); 如果返回值是原始值则返回原始值结果;
- 如果 2 的结果不是原始值, 调用 input.toString(), 如果返回值是原始值则返回原始值结果;
- 如果 3 的结果不是原始值, 抛出 TypeError 异常;
PreferredType = String: 类似于 Number :
- input 是原始值, 返回原始值;
- input 不是原始值, 调用 input.toString(); 如果返回值是原始值则返回原始值结果;
- 如果 2 的结果不是原始值, 调用 input.valueOf(), 如果返回值是原始值则返回原始值结果;
- 如果 3 的结果不是原始值, 抛出 TypeError 异常;
ToNumber
|
|
ToString
|
|
valueOf方法和toString方法详解
首先 valueOf() 和 toString() 是 Object.prototype 的方法, 也就是所有的对象都有这两个方法;
valueOf() 总的原则是能转化为原始值则转化为原始值, 不能转化为原始值的返回 this, 也就是对象本身, Date 对象转化为 毫秒级数值
1234567891011Number('123').valueOf() // 123String('123fs').valueOf() // '123fs'Boolean(true).valueOf() // truenew Date().valueOf() // 1530706938289var arr = ['1', '2'];arr.valueOf() // [ '1', '2' ] === arr => true 等于 自身var obj = {};obj.valueOf() // {} === obj => true 等于自身
toString() 将对象转化成字符串形式, 重写了 toString() 的调用自己的 toString() 方法, 其余的调用 Object.prototype.toString()
123456789101112131415161718192021222324252627282930Number.prototype.hasOwnProperty('toString'); // trueBoolean.prototype.hasOwnProperty('toString'); // trueString.prototype.hasOwnProperty('toString'); // trueArray.prototype.hasOwnProperty('toString'); // trueDate.prototype.hasOwnProperty('toString'); // trueRegExp.prototype.hasOwnProperty('toString'); // trueFunction.prototype.hasOwnProperty('toString'); //var num = new Number('123sd');num.toString(); // 'NaN'var str = new String('12df');str.toString(); // '12df'var bool = new Boolean('fd');bool.toString(); // 'true'var arr = new Array(1,2);arr.toString(); // '1,2'var d = new Date();d.toString(); // "Wed Jul 04 2018 20:22:09 GMT+0800 (CST)"var func = function () {}func.toString(); // "function () {}"var obj = new Object({});obj.toString(); // "[object Object]"Math.toString(); // "[object Math]"
隐式转换的例子
|
|
|
|
分析:
- 当执行a == 1 && a == 2 && a == 3 时,会从左到右一步一步解析,首先 a == 1,会进行上面第9步转换。ToPrimitive(a, Number) == 1。
- ToPrimitive(a, Number),按照上面原始类型转换规则,会先调用 valueOf 方法,a 的 valueOf 方法继承自 Object.prototype。返回a本身,而非原始类型,故会调用 toString 方法。
- 因为 toString 被重写,所以会调用重写的 toString 方法,故返回1,注意这里是 i++,而不是 ++i,它会先返回i,在将i+1。故 ToPrimitive(a, Number) = 1。也就是 1 == 1,此时 i = 1 + 1 = 2。
- 执行完 a == 1返回 true,会执行 a == 2,同理,会调用 ToPrimitive(a, Number),同上先调用 valueOf 方法,在调用 toString 方法,由于第一步,i = 2 此时,ToPrimitive(a, Number) = 2, 也就是2 == 2, 此时i = 2 + 1。
- 同上可以推导 a == 3 也返回 true。故最终结果 a == 1 && a == 2 && a == 3 返回 true
- 本文链接:https://bummingboy.top/2017/07/05/JavaScript - 数据类型及隐式转换/
- 版权声明:BummingBoy