基本数据类型
boolean, Number, String, Object, Number, Symbol, Undefined, Null
symbol
Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
let s = Symbol();
typeof s
// "symbol"
上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是 Symbol 数据类型,而不是字符串之类的其他类型。
注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
显示转化
Number
基本类型

引用类型

valueOf 方法:
JavaScript calls the valueOf method to convert an object to a primitive value. You rarely need to invoke the valueOf method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.
custom function
function MyNumberType(n) {
this.number = n;
}
MyNumberType.prototype.valueOf = function() {
return this.number;
};
var myObj = new MyNumberType(4);
myObj + 3; // 7
String

Boolean
Boolean(0) // false
Boolean(+0) // false
Boolean(-0) // false
+0 === 0 // true
-0 === 0 // true
-0 === +0 // true
Boolean(null) // false
Boolean(NaN) // false
Boolean(undefined) // false
Boolean('') // false
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script>
// Number
console.log(Number(123)) // 123
console.log(Number('123')) // 123
console.log(Number('123abc')) // NaN
console.log(Number(false)) // 0
console.log(Number(true)) // 1
console.log(Number(undefined)) // NaN
console.log(Number(null)) // 0
var a = { b: 1}
console.log(Number(a)) // NaN
var s = Symbol()
// Number(s)
//Uncaught TypeError: Cannot convert a Symbol value to a number
// String
console.log(String(123)) // 123
console.log(String('123asd')) // 123asd
console.log(String(true)) // true
console.log(String(false)) // false
console.log(String(undefined)) // undefined
console.log(String(null)) // null
console.log(String(s)) // Symbol
console.log(String(a)); // [object Object]
var c = {d: 3};
c.toString() // "[object Object]"
c.valueOf() // {d: 3}
c.valueOf().toString(); // "[object Object]"
console.log(String(c)); // "[object Object]"
var d = {
f: 9,
toString: function () {
return 'aoligei';
}
}
console.log(d.toString()) // "aoligei"
console.log(String(d)) // "aoligei"
var d = {
f: 9,
toString: function () {
return {m: 'vvv'};
}
}
console.log(String(d)) // Cannot convert object to primitive value
var d = {
f: 9,
toString: function () {
return {m: 'vvv'};
},
valueOf: function () {
return 'vvv'
}
}
console.log(String(d)) // 'vvv'
var d = {
f: 9,
toString: function () {
return {m: 'vvv'};
},
valueOf: function () {
return {v: 'sss'}
}
}
console.log(String(d)) // Cannot convert object to primitive value
// Boolean
//
Boolean(0) // false
Boolean(+0) // false
Boolean(-0) // false
+0 === 0 // true
-0 === 0 // true
-0 === +0 // true
Boolean(null) // false
Boolean(NaN) // false
Boolean(undefined) // false
Boolean('') // false
Boolean('aaa') // true
Boolean([]) // true
Boolean({}) // true
</script>
</body>
</html>
隐式转换触发方法
四次运输 比如 +
逻辑判断 比如 if
native 调用 console, alert
JS对于Object与Array的设计
在JS中所设计的Object纯对象类型的valueOf与toString方法,它们的返回如下:
valueOf方法返回值: 对象本身。
toString方法返回值: "[object Object]"字符串值,不同的内建对象的返回值是"[object type]"字符串,"type"指的是对象本身的类型识别,例如Math对象是返回"[object Math]"字符串。但有些内建对象因为覆盖了这个方法,所以直接调用时不是这种值。(注意: 这个返回字符串的前面的"object"开头英文是小写,后面开头英文是大写)
你有可能会看过,利用Object中的toString来进行各种不同对象的判断语法,这在以前JS能用的函数库或方法不多的年代经常看到,不过它需要配合使用函数中的call方法,才能输出正确的对象类型值,例如:
> Object.prototype.toString.call([])
"[object Array]"
> Object.prototype.toString.call(new Date)
"[object Date]"
Array and Function 独特性
Array(数组)很常用到,虽然它是个对象类型,但它与Object的设计不同,它的toString有覆盖,说明一下数组的valueOf与toString的两个方法的返回值:
valueOf方法返回值: 对象本身。(与Object一样)
toString方法返回值: 相当于用数组值调用join(',')所返回的字符串。也就是[1,2,3].toString()会是"1,2,3",这点要特别注意。
Function对象很少会用到,它的toString也有被覆盖,所以并不是Object中的那个toString,Function对象的valueOf与toString的两个方法的返回值:
valueOf方法返回值: 对象本身。(与Object一样)
toString方法返回值: 函数中包含的代码转为字符串值
习题
+ 强制转化为数字
+[] // 0
{} + [] // 0 {}
{} + {} // NAN(Firefox) or "[object Object][object Object]" chrome
{} + {}的结果是会因浏览器而有不同结果,Chrome(v55)中是[object Object][object Object]字符串连接,但其它的浏览器则是认为相当于+{}运算,得出NaN数字类型。
[].valueOf() // []
[].valueOf().toString() // ""
[] + {} // "[object Object]"
{} + [] // 0 thee first {} as an empty code block and ignores it, {} + []的结果是相当于+[],结果是0数字类型。
{} + {} // "[object Object][object Object]"
true + true // 2
1 + {a: 1} // "1[object Object]"
Number({a: 1}) // NaN
String(123) // "123"
特殊情况
空对象 + 空数组
上面同样的把{}当作区块语句的情况又会发生,不过这次所有的浏览器都会有一致结果,如果{}(空对象)在前面,而在后面时,前面(左边)那个运算元会被认为是区块语句而不是对象字面量。
所以{} + []相当于+[]语句,也就是相当于强制求出数字值的Number([])运算,相当于Number("")运算,最后得出的是0数字。
> {} + []
0
> [] + {}
"[object Object]"
特别注意: 所以如果第一个(前面)是{}时,后面加上其他的像数组、数字或字符串,这时候加号运算会直接变为一元正号运算,也就是强制转为数字的运算。这是个陷阱要小心。
Date对象
Date对象的valueOf与toString的两个方法的返回值:
valueOf方法返回值: 给定的时间转为UNIX时间(自1 January 1970 00:00:00 UTC起算),但是以微秒计算的数字值
toString方法返回值: 本地化的时间字符串
Date对象上面有提及是首选类型为"字符串"的一种异常的对象,这与其他的对象的行为不同(一般对象会先调用valueOf再调用toString),在进行加号运算时时,它会优先使用toString来进行转换,最后必定是字符串连接运算(concatenation),例如以下的结果:
> 1 + (new Date())
> "1Sun Nov 27 2016 01:09:03 GMT+0800 (CST)"
要得出Date对象中的valueOf返回值,需要使用一元加号(+),来强制转换它为数字类型,例如以下的代码:
> +new Date()
1480180751492
var d = new Date();
d.toString() // "Sat Feb 22 2020 16:20:08 GMT+0800 (China Standard Time)"
d.valueOf() // 1582359608095
Symbols类型
ES6中新加入的Symbols数据类型,它不算是一般的值也不是对象,它并没有内部自动转型的设计,所以完全不能直接用于加法运算,使用时会报错。