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 深渊

  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/dyqblog/p/10366795.html
Copyright © 2011-2022 走看看