类型
一共包括下面七种数据类型
- String
- Number
- Boolean
- Null
- Undefined
- Symbol
- Object
Undefined、Null
Undefined 类型表示未定义,它的类型只有一个值,就是undefined。一般使用void 0 来获取一个undefined的值。
Null 类型也只有一个值,就是 null,它的语义表示定义了但是为空值.并且null是Javascript的一个关键字。所以一般不会把变量赋值为undefined,这样可以保证所有值为undefined的变量,都是从未赋值的自然状态
Boolean
Boolean有两个值true和false,表示逻辑意义上的真和假。
String
字符串的最大长度为2^53-1,Javascript中的字符串是永远无法变更的。一旦字符串创建出来无法用任何方式改变字符串的内容,所以字符串具有值类型的特征。
Number
Javascript的Number类型基本符合双精度浮点数规则
。并且引入了几个特殊的情况:
- NaN (Not a Number) 非数字
- Infinity 正无穷大
- -Infinity 负无穷大
Javascript的+0和-0的检测可以通过1/x 是Infinity或者-Infinity来进行区分。 根据浮点数的定义,非整数的Number类型无法用==来比较。
经典的面试题: 在Javascript中,为什么0.1+0.2!=0.3 ? (这个面试题错误的不是结论,而是比较的方法,这个题里面涉及到双精度浮点小数部分转化为2进制计算的过程中舍掉精度而造成值不准导致,正确的比较方法如下:)
// 绝对值小于最小精度
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
复制代码
Symbol
Symbol可以具有字符串类型的描述,即使描述相同,Symbol也不相等。
var mySymbol = Symbol("my symbol");
复制代码
可以使用Symbol.iterator来自定义for..of在对象上的行为。
var o = new Object
o[Symbol.iterator] = function() {
var v = 0
return {
next: function() {
return { value: v++, done: v > 10 }
}
}
};
for(var v of o)
console.log(v); // 0 1 2 3 ... 9
复制代码
类型转换
当使用==的时候会进行类型转换。
StringToNumber
- parseInt(string,进制) 一般建议传入第二个参数
- parseFloat 会直接把字符串当做十进制来解析
- 多数情况下Number转化是最好的选择。
装箱转换
每一种基本数据类型String、Number、Boolean、Symbol在对象中都有相对应的类。所谓装箱转换就是把基本数据类型转换为对应的对象。
Object.prototype.toString.call可以准确的识别对象对应的基本类型。但是需要注意的是call本身会产生装箱操作。所以需要配合typeof来区分基本数据类型还是对象类型。
拆箱转换
Javascript标准中规定了ToPrimitive函数,它是对象类型到基本数据类型的转换。并且对象内部有valueOf和toString方法。当对对象进行不同的拆箱的时候调用顺序会有所不同。(还需要注意一个点就是当对象作为数组arr的变量取值的时候arr[obj]是先调用obj的toString的
)
// valueOf 和 toString必须返回原始值 否则继续向下执行 最终抛出错误
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError
// 先toString后valueOf
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
String(o)
// toString
// valueOf
// TypeError
// Symbol.toPrimitive的优先级最高
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello"}
console.log(o + "") // 如果没有Symbol.toPrimitive,其实这个也是先调valueOf 然后再是toString
// toPrimitive
// hello
复制代码
看下加法运算符的规范: