zoukankan      html  css  js  c++  java
  • javascript 数据类型 -- 分类

    一、概念

      Javascript 中有6中基本类型(也称 原始类型/原始值): number 、 sring 、 boolean 、 symbol 、 undefined 和 null ,和1种引用类型(也称 复杂类型/引用值/对象): object 。

    二、分类

    基本类型就是最简单的数据段,是不可拆分的最小单元,没有属性和方法。

      string 类型:由UTF-16编码的字符集组成的不可变的有序序列,默认为 "", 即空字符串,length为0。

    // 定义
    var a = "fdsaf"
    typeof a                            // string
    console.log(a, a.length)            // fdsaf 5
    var a = String("gfdafd")
    typeof a                            // string
    console.log(a, a.length)            // fdsaf 6
    var a = new String("fdsaf")
    typeof a                            // object
    console.log(a, a.length)            // String {"fdsaf"} 5
    
    
    a[0] = 'e'                          // 返回 e
    console.log(a)                      // 返回 fdsaf,即 a 本身没有改变,所以string做为基本类型,其实是不可变的。
    

      

      number 类型:用来表示直接在程序中出现的数字,有整型字面量、浮点型字面量(也有的称之为直接量,整型直接量、浮点型直接量)和特殊值NaN、Infinity

        其中整型字面量包括了二进制(仅由0、1两个整数组成)、八进制(以0开头,随后跟上0-7之间的整数)、十进制(仅由0-9的数字组成)、十六进制(以 0x、0X 开头,随后跟上0-9之间的整数和 a(A)-f(F) 之间的字母组成)。其他几种类型都可以用  parseInt(string, radix)  方法转换成十进制的整型。

        浮点型字面量则由整数部分、小数点和小数部分组成,也可使用指数计数法,即实数后跟字母 e 或 E,加 +/- 号,再加一个整数的指数完成。浮点型字面量由于计算机是二进制表示法,所以并不能准确地表示0.1这种简单的数字,这种情况下,可以引用第三方包 BigNumber() 解决这个问题。

        NaN 和 Infinity 是特殊的 number 类型,分别用来表示 非数字值 和 正无穷大。

    // 定义
    var b = 1234.567                 // 1234.567
    typeof b                         // number
    var b = Number("1234.567")       // 1234.567
    typeof b                         // number
    var b = new Number("1234.567")   // Number {12345.678}
    typeof b                         // object
    
    var b = parseInt("1234.567")     // 十进制1234, parseInt,第二个参数默认为10进制,永远返回十进制整型。
    
    parseInt('0101', 2)              // 十进制5, 0*8+1*4+0*2+1*1 = 5
    
    parseInt('0723', 8)              // 十进制467, 7*64+2*8+3*1 = 467
    
    parseInt('oxff', 16)             // 十进制255, 15*16+15*1 = 255
    
    6.02 e 23                        // 6.02 乘以 10 的 23 次方
    1.47 E -23                       // 1.47 乘以 10 的 -23 次方
    
    var x = 0.2 - 0.1                // 0.1
    var y = 0.3 - 0.2                // 0.09999999999999998
    y === x                          // false
    y = new BigNumber(0.3) - new BigNumber(0.2)
    y === x                          // true
    0/0                              // NaN, not a number
    1/0                              // Infinity, 无穷大

      boolean 类型:指代真或假、开或关、是或否。这个类型只有两个值,就是 true 和 false。布尔值经常出现在 判断语句、逻辑运算和控制结构中,比如 >/</==/!=/===/!==、if/else、三元表达式、||/&&/! 等,在这些情况下,下列6组数据 0/-0/NaN/""/undefined/null 都会转换成假值(false),其他值(包括所有引用类型)都会转化成真值(true)。

    // 定义
    var c = true                      // true
    typeof c                          // boolean
    var c = Boolean(true)             // true
    typeof c                          // boolean
    var c = new Boolean(true)         // Boolean {true}
    typeof c                          // object
    
    var x = {}
    console.log(x ? true : false)     // true
    var x = []
    console.log(x ? true : false)     // true
    var x = null
    console.log(x ? true : false)     // false
    var x = undefined
    console.log(x ? true : false)     // false
    var x = ""
    console.log(x ? true : false)     // false
    var x = 0
    console.log(x ? true : false)     // false
    var x = NaN
    console.log(x ? true : false)     // false

      symbol 类型:ES6中引入的第6种基本类型,为了解决ES5中属性名冲突问题,而引入的特殊类型。值只能通过 Symbol() 函数生成,不能使用 new 操作符,因为没有构造器。且其生成的每一个值,都是独一无二的,因而能够解决冲突问题。

    //定义
    var s1 = Symbol()
    console.log(s1)                            // Symbol()
    var s2 = new Symbol()                      // VM3934:1 Uncaught TypeError: Symbol is not a constructor
    
    
    // Symbol 函数的参数,起到的是描述的作用,标志的是每一个变量的名字。即使参数相同,结果也是不同的。
    var s3 = Symbol('foo')
    var s4 = Symbol('foo')
    var s5 = Symbol('bar')
    console.log(s3, s4, s5)                    // Symbol('foo'), Symbol('foo'), Symbol('bar')
    s3 === s4                                  // false
    s4 === s5                     // false
    
    // Symbol 做为对象属性值时的使用方式
    var mySymbol = {
      testVal: Symbol('testValue'),
      testFn: Symbol('testFunction')
    }
    
    // 方法一
    var o = {}
    o[mySymbol.testVal] = "hello"
    o[mySymbol.testFn] = function(){}
    
    // 方法二
    var o = {
      [mySymbol.testVal] = "hello",
      [mySymbol.testFn](){
        // do something
      }
    }
    
    // 方法三
    var o = {}
    Object.defineProperty(o, mySymbol.testVal, {value: 'hello'})
    Object.defineProperty(o, mySymbol.testFn, {value: function(){}})
    
    console.log(o, o[mySymbol.testVal])         // symbol 类作为属性在调用时,不能使用.运算符,只能通过[]进行调用
    // 打印出来的结果是:
    // {
    //   Symbol(testFunction):f[mySymbol.testFn](),
    //   Symbol(testValue):"hello"
    // }
    // "hello"

    特别的:

      1、String/String()、Number/Number()、Boolean/Boolean()、Symbol/Symbol()

        对于 string、number、boolean 和 symbol 类,基本都可以通过 直接定义(除 symbol 外)、方法定义(String()、Number()、Boolean()、Symbol())、构造器定义(除 symbol 外),那么我们平常见到的 String、Number、Boolean、Symbol 与 String()、Number()、Boolean()、Symbol() 有什么区别和联系呢?

    String                           // ƒ String() { [native code] },指向的是 String 构造函数
    typeof String                    // function
    String()                         // "",指向的是 String 函数不传值运行时的默认返回值
    typeof String()                  // string
    new String()                     // String {""},指向的是 String.constructor 构造器,创建出来的对象
    typeof new String()              // object
    
    Number                           // ƒ Number() { [native code] },指向的是 Number 构造函数
    typeof Number                    // function
    Number()                         // 0,指向的是 Number 函数不传值运行时的默认返回值
    typeof Number()                  // number
    new Number()                     // Number {""},指向的是 Number.constructor 构造器,创建出来的对象
    typeof new Number()              // object
    
    Boolean                          // ƒ Boolean() { [native code] },指向的是 Boolean 构造函数
    typeof Boolean                   // function
    Boolean()                        // false,指向的是 Boolean 函数不传值运行时的默认返回值
    typeof Boolean()                 // boolean
    new Boolean()                    // Boolean {""},指向的是 Boolean.constructor 构造器,创建出来的对象
    typeof new Boolean()             // object
    
    Symbol                           // ƒ Symbol() { [native code] },指向的是 Symbol 构造函数
    typeof Symbol                    // function
    Symbol()                         // Symbol(),指向的是 Symbol 函数不传值运行时的默认返回值
    typeof Symbol()                  // symbol
    new Symbol()                     // Uncaught TypeError: Symbol is not a constructor

        由上可知,String、Number、Boolean、Symbol 都属于对应类型的函数,而 String()、Number()、Boolean()、Symbol() 则对应的是函数运行的默认结果。

      2、包装对象

        基本类型的特点是不可变的没有属性及方法的。但在实际运行中,我们常会看到 s.length(属性) 和 s.substring(方法) 等用法,为什么可以这么用呢?这就的归功于包装对象了。

        包装对象是特殊的引用类型。每当读取字符串、数字或布尔值的属性或方法时,创建的临时对象称做包装对象

         背后的故事是:只要引用了字符串s的属性,JavaScript就会将字符串值通过调用new String(s)的方式转换成临时对象,这个对象继承了字符串(String)对象的方法,并被用来处理属性的引用。一旦属性引用结束,这个新创建的对象就会被销毁。

    var str = 'hello'
    console.log(str.length)
    str.subStr(2)
    consol.log(str)
    str.len = 8
    console.log(str.len)

        结合包装对象的定义,猜猜3个 console 输出的结果?试一下,然后点开下面的代码,查看背后的故事。

    var str = 'hello'
    var S = new String(str)         // 用变量 s 创建了一个临时的包装对象 S
    console.log(S.length)           // 5,读取的是 S 的属性值 length
    S.subStr(2)                     // 'llo',在 S 上截取从索引号 2 开始的所有字符
    console.log(str)                // 'hello',并不改变原有 s 的值,即不可变性
    S.len = 8                       // 为包装对象 S 设置一个属性 len,并赋值 8
    S = null                        // 在没有属性引用后,S 被销毁
    console.log(str.len)            // undefined,由于 len 其实是设在临时对象 S 上的,且此时已被销毁,所以 s 上并没有 len 属性,返回 undefined

        类似的,number 型和 boolean 型也会创建自己的包装对象。且包装对象不仅仅在调用属性和方法是其效果,在基本类型参加数学运算或布尔运算时,也会被调用起来把值转换成需要的类型。

      null 类型:是 javascript 的关键词,也是这一类型里的唯一值。表示空对象指针,运用 typeof 运算符返回的结果是 object 。可以用来表示对象是"无值"的,即有预期空引用/空对象的占位符。为了与定义却未赋值的会返回 undefined 的变量区别,最佳实践是,在变量定义时即给定初始值占位。

    typeof null           // object

      undefined 类型:是 javascript 预定义的全局变量,但不是关键词。也是自有类型里的唯一值,表示更深层次的“空值”,即声明后未初始化的值,也可以称为没有预期的空值

        定义时未给初始值,返回 undefined ,函数没有返回任何值,则返回 undefined ,查询不存在的对象属性或数组元素也返回 undefined ,引用没有提供实参的函数形参的值,也会返回 undefined 。

        特别的,在最早的ECMAScript3中 undefined 是可读可写的,可以作为变量名进行赋值操作;在ECMAScript 5 中做了修正undefined作为只读变量。所以在现今 ES5 甚至 ES6 普及的今天,用 undefined 做变量的操作已经很少见了,但在一些 Jquery 插件中,为了防止 undefined 被改写,还是做了些兼容操作。

    var foo;
    console.log(foo)                   // undefined,定义但未赋值
    
    var foo = [1,2,3,4]
    console.log(foo[6])                // undefined,数字第7位元素不存在
    
    var foo = {'a':1,'b':2,'c':3}
    console.log(foo.d)                 // undefined,对象的d属性不存在
    
    (function foo () {})()             // undefined,函数没有返回值
    
    (function foo (val) {
        console.log(val)            
    })()                               // undefined,没有传实参的形参。
    
    // 用来避免 undefined 在老版本中被重写的操作
    (function ($, undefined){ })(jQuery)
    

      

      

    特别的:对于 null 和 undefined 两种类型可能带来的代码上的困扰,有说法是 undefined 是无值的基本类型占位符,null 是无值的引用类型占位符。所以最佳实践是

      1、变量在定义时即赋上初始值占位,string 型用 "",number 型用 0,boolean 型用 false,object 型则用 {},未知或可变类型用 null。

      2、当对象不再必需时,将它显性得分配一个 null 值,以有效地清理引用。

      3、在判断语句时,尽量不用 null 类型进行判断,而选择用 undefined,因为既包括未定义的值也包括了没有内容的空值。而只有在对值的结果有 null 的预期时,可使用 null 类型进行判断。

    var str = ""
    var nub = 0
    var flag = false
    var obj = {}
    var arr = []
    var x = null
    
    var O = new Object()
    // do sth.
    O = null
    
    if (value !== null) {         // 仅判断 val 不等于 null 不足以证明传入的值是合法的。
      // do sth.
    }
    if (value) {              // 由于 undefined 和 null 在判断语句中会自动转化成 false,所以这种判断更全面
      // do sth.
    }
    
    var div = document.getElementById('id')
    if (div !== null) {          // 只有当对结果有 null 的预期时,用 null 判断才更准确。
      // do sth.
    }
    

      

      

    引用类型(对象)是属性的集合,属性由“键值对”构成。常见的引用类型有数组( Array ,“键值对”的有序集合)、日期( Date )、正则( RegExp )、数学( Math )、错误( Error )、函数( Function )。当用 new 运算符初始化一个函数,新建一个对象时,这个函数被称为 构造函数: new Person() 。

      

    三、知识结构图

      

    四、拓展阅读

      ES6 Symbol 类详解

      包装对象

      理解 null 和 undefined

      探究 null 和 undefined 深渊

  • 相关阅读:
    2020学习 04 python 爬取某政府网站信件
    2020学习03
    2020学习02
    阅读笔记--《一线架构师实践指南》--Pre-architecture阶段
    重构“信息领域热词分析”,实现六种质量属性战术
    pycharm错误:Error updating package list: connect timed out解决
    python连接mysql数据库——编码问题
    阅读笔记--《大型网站技术架构》—02架构
    python查询MySQL数据库的表以及所有字段
    python连接mysql数据库——版本问题
  • 原文地址:https://www.cnblogs.com/dyqblog/p/10366795.html
Copyright © 2011-2022 走看看