美文网首页让前端飞程序员前端开发笔记
【三】JavaScript类型:关于类型,有哪些你不知道的细节?

【三】JavaScript类型:关于类型,有哪些你不知道的细节?

作者: alanwhy | 来源:发表于2019-02-06 11:30 被阅读0次

    抛出问题

    • 为什么有的编程规范要求用 void 0 代替 undefined?
    • 字符串有最大长度吗?
    • 0.1+0.2不是等于0.3吗?为什么js里面不是这样?
    • es6中的symbol是什么?
    • 为什么给对象添加的方法能用在基本类型上?

    一、类型

    js语言的每一个值都属于某一种数据类型。js规定了7种语言类型。广泛的用于变量、函数参数、表达式、函数返回值等场合。分别是

    • undefined
    • null
    • boolean
    • string
    • number
    • symbol
    • object

    1、undefined、null

    undefined表示未定义,它的类型只有一个值,就是undefined。但是js的代码undefined是一个变量,并非一个关键字,会造成可能无意中的篡改,所以使用void 0来获取undefined的值
    null表示空值,是js的关键字,所以在任何代码中,都可以用null来获取null的值

    2、boolean

    boolean有两个值,true和false,表示逻辑上的真和假,同样就具有关键字的true和false来表示

    3、string

    string表示文本数据。最大长度是2^53-1,一般来说是够用的。但是string的意义并非“字符串”,而是UTF16编码,我们平时的charAt、charCodeAt、length等方法都是针对UTF16编码。所以,字符串最大的长度其实是受字符串的编码长度影响的。

    4、number

    number表示我们通常意义上的“数字”,大致对应数学中的有理数,当然在计算机中是有精度限制的
    js中的number类型有18437736874454810627(即 264-253+3)个值,它基本符合IEEE 754-2008规定的双精度浮点数规则,但是也有几个例外

    • NaN,占用了9007199254740990,这是符合规则的数字
    • Infinity,无穷大
    • -Infinity,无穷小

    根据双精度浮点数的定义,number类型中有效的整数范围是-0x1fffffffffffff至0x1fffffffffffff,所以number无法精确表示此范围外的整数

    非整数的number类型无法使用==或者===来比较,比如

    console.log(0.1 + 0.2 == 0.3)
    // false
    

    但是我们可以这样干

    console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
    // true
    

    这是使用了js提供的最小精度值,检查等式左右两边差的绝对值是否小于最小精度。

    5、symbol

    symbol是es6中新引入的类型,是一切非字符串对象key的集合,在es6的规范中,整个对象系统被用symbol重塑
    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
    

    6、object

    object是js中最复杂的类型。也是js的核心机制之一,object是对象的意思。

    在js中,对象的定义是“属性的集合”,属性分为数据属性和访问器属性,二者都是key-value的结构,key可以是字符串或者symbol类型

    说到对象,我们一定要说一下“类”
    在js中,“类”仅仅是运行时对象的一个私有属性,而js中是无法自定义类型的
    js中有几个基本类型,都在对象中有自己的“亲戚”

    • number
    • string
    • boolean
    • symbol

    所以要知道,3和 new Number(3)是完全[图片上传中...(image.png-75b66f-1549423004254-0)]
    不同的值,一个是number的类型,一个是对象类型

    二、类型转换

    因为js是弱类型语言,所以类型转换发生十分频繁,看图


    image.png

    装箱变换

    装箱变换即把基本类型转换成对应的对象

    拆箱变换

    拆箱变换即在js中,规定了ToPrimitive函数,它是对象类型到基本类型的转换

        var o = {
            valueOf : () => {console.log("valueOf"); return {}},
            toString : () => {console.log("toString"); return {}}
        }
    
        o * 2
        // valueOf
        // toString
        // TypeError
    

    三、写在最后

    除了7种用语言类型,还有一些语言的实现者更关心的规范类型

    • list和record:用于描述函数传参的过程
    • set:主要用于解释字符集等
    • completion record:用于描述异常、跳出等语句执行过程
    • reference:用于描述对象属性访问、delete等
    • property descriptor:用于描述对象的属性
    • lexical environment和environment record:用于描述变量和作用域
    • data block:用于描述二进制数据

    关于typeof

    typeof是用返回操作数的类型,但是我们可以看下图


    image.png

    可以看出typeof对于object和function是有问题的,这确实是缺陷,但是js之父也说已经错过了修改它的最佳时机了。。

    参考原文:JavaScript类型:关于类型,有哪些你不知道的细节?

    相关文章

      网友评论

        本文标题:【三】JavaScript类型:关于类型,有哪些你不知道的细节?

        本文链接:https://www.haomeiwen.com/subject/eowbsqtx.html