数据类型 转化 笔记

171 阅读6分钟

基本数据类型

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数据类型,它不算是一般的值也不是对象,它并没有内部自动转型的设计,所以完全不能直接用于加法运算,使用时会报错。

重要文章

2ality.com/2012/01/obj…

segmentfault.com/a/119000000…

www.cnblogs.com/ziyunfei/ar…