# 数据类型
基础数据类型: undefined, null, Number, String, Boolean, Symbol (ES6+) 引用数据类型: Object(Object, Array, Date, RegExp, Function)
基础数据类型 值直接存储在相应 栈内存 上的, 使用时是按值访问; 引用数据类型 地址存储在 占内存上, 内容存储在 堆内存上, 使用时是按 引用访问;
**注: ** Number, Boolean, String 三种类型 也可以通过 new 关键字创建对应的 基本包装类型, 包装类型的实例
# 隐式转换
涉及到隐式转换的运算符最多的是 + 和 ==, -*/等运算符只会针对 number 类型;
- 将值转换为原始值 ToPrimitive()
- 将值转换为数字 ToNumber();
- 将值转化为字符串 ToString();
# ToPrimitive(input, PreferredType?)
input是要转换的值,PreferredType是可选参数,可以是Number或String类型, 只是一个转换标志,转化后的结果并不一定是这个参数所值的类型,但是转换结果一定是一个原始值(或者报错), 也就是说设置 Number 时也可能转换为 string, 设置为 String 时 也可能转化为 Number;
当 PreferredType 未设置时, 按照下面规则设置:
|
|
PreferredType = Number:
|
|
PreferredType = String: 类似于 Number
|
|
# ToNumber
|
|
# ToString
|
|
# valueOf方法和toString方法详解
首先 valueOf() 和 toString() 是 Object.prototype 的方法, 也就是所有的对象都有这两个方法;
-
valueOf() 总的原则是能转化为原始值则转化为原始值, 不能转化为原始值的返回 this, 也就是对象本身, Date 对象转化为 毫秒级数值
1 2 3 4 5 6 7 8 9 10 11
Number('123').valueOf() // 123 String('123fs').valueOf() // '123fs' Boolean(true).valueOf() // true new Date().valueOf() // 1530706938289 var arr = ['1', '2']; arr.valueOf() // [ '1', '2' ] === arr => true 等于 自身 var obj = {}; obj.valueOf() // {} === obj => true 等于自身
-
toString() **将对象转化成字符串形式, 重写了 toString() 的调用自己的 toString() 方法, 其余的调用 Object.prototype.toString() **
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Number.prototype.hasOwnProperty('toString'); // true Boolean.prototype.hasOwnProperty('toString'); // true String.prototype.hasOwnProperty('toString'); // true Array.prototype.hasOwnProperty('toString'); // true Date.prototype.hasOwnProperty('toString'); // true RegExp.prototype.hasOwnProperty('toString'); // true Function.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]"
# 隐式转换的例子
|
|
|
|
1、当执行a == 1 && a == 2 && a == 3 时,会从左到右一步一步解析,首先 a == 1,会进行上面第9步转换。ToPrimitive(a, Number) == 1。 2、ToPrimitive(a, Number),按照上面原始类型转换规则,会先调用valueOf方法,a的valueOf方法继承自Object.prototype。返回a本身,而非原始类型,故会调用toString方法。 3、因为toString被重写,所以会调用重写的toString方法,故返回1,注意这里是i++,而不是++i,它会先返回i,在将i+1。故ToPrimitive(a, Number) = 1。也就是1 == 1,此时i = 1 + 1 = 2。 4、执行完a == 1返回true,会执行a == 2,同理,会调用ToPrimitive(a, Number),同上先调用valueOf方法,在调用toString方法,由于第一步,i = 2此时,ToPrimitive(a, Number) = 2, 也就是2 == 2, 此时i = 2 + 1。 5、同上可以推导 a == 3也返回true。故最终结果 a == 1 && a == 2 && a == 3返回true