JavaScript 回顾学习:数据类型

基础成就高度

Posted by Mopecat on July 27, 2019

概述

ECMAScript中有5中基本数据类型:Undefined,Null,Boolean,Number,String,还有一种复杂数据类型对象(Object)Object本质上是由一组无序的名值对组成的,JavaScript同样还定义了另外两种特殊对象:

  • 数组—>表示带编号的值的有序组合
  • 函数—>函数是具有与它相关联的可执行代码的对象,通过调用函数来运行可执行代码,并返回运算结果 综上为ES5的全部数据类型,ES6新出了一种数据类型为Symbol,表示独一无二的值。 函数,数组,对象在后续文章中会有详解(写完后将加上链接,提前埋坑)。本篇文章将回顾学习5种基本类型和Symbol及数据类型之间的转化。

    基本数据类型

    undefined

    Undefined类型只有一个值,即undefined,在使用var声明变量但没有对这个变量初始化时,这个变量的值就是undefined

  • 注意:我们没有必要显式的将一个变量初始化为undefined。因为没有赋值初始化的变量就是undefined这样更有利于我们比较赋值还是未赋值的变量。

Null

Undefined类似,Null类型也只有一个值nullnull表示是一个空对象指针。所以当type of null的时候返回'object'

  • undefined不同的是,当我们明确这个变量是将用来保存对象的时候,我们最好将这个变量初始化为null,这样有利于我们只要检查当前这个对象的值是不是null就可以知道当前的变量是否已经保存了一个对象的引用。同时也能更好的区别undefinednull

Boolean 类型

Boolean类型只有两个值:truefalse 这个类型在开发中可以说是用的最多的类型了,大多数判断都是用这个类型来完成的。

  • 注意: 所有的其他的类型都可以转化为Boolean类型。关于转化的情况下面会讲到。

Number类型

简而言之就是数字,分为整数和浮点数。最基本的整数数字值是十进制整数的也就是我们平时用的数字,除了十进制,还有八进制和十六进制。

  • 八进制0开头的后面的每位数都是(0~7)如:
    1
    
      var num = 0666; // 八进制的438
    

    但是如果不符合规则了,那前面的0就会被忽略,后面数值按照十进制解析,如:

    1
    
       var num1 = 0668; // 不符合规则 解析为668 
    

    (严格模式八进制是无效的)

  • 十六进制的前两位是0后面跟任何十六进制的数字(0~9及A~F) 在进行计算的时候八进制和十六进制的数值都会被转化为十进制数值。

浮点数,就是通俗理解的小数。由于舍入误差原因所以不要将浮点数作为判断依据。 数字可以用科学计数法e表示,如:

1
2
var int = 3e3; // 表示3000,相当于3乘以10的3次幂
var float = 3e-3 // 表示0.003 ,相当于3乘以10的-3次幂

数字在javascript中是有范围的:5e-324~1.7976931348623157e308;一般情况是用不到的知道就行,超过范围的数值会自动被转换为Infinity(区分正负)。如果出现了也可以用isFinite()函数进行识别判断,在范围内转换为true

关于数值最后还有一个特殊的值: NaN 代表非数值英文直译缩写(Not a Number);用于本来是要返回数值的操作没有返回数值就会返回NaNNaN有两个特点需要注意一下:

  • 任何涉及NaN的操作都返回NaN
  • NaN与任何值都不相等,包括NaN本身。 因为以上两个比较难受的特点会导致我们没法判断一个值是不是NaN,所以JavaScript给我们定义了一个函数:isNaN()这个函数接受一个参数,如果能转化位数值返回false,不能则true,以下有几个书上非常经典的例子,请切记(面试可能会用到,哈哈哈哈哈):
    1
    2
    3
    4
    5
    
    isNaN(NaN)     // true
    isNaN(10)      // false (10是一个数值)
    isNaN('10')    // false ('10'可以被转化为数值10)
    isNaN('blue')  // true  (不能被转化为数值)
    isNaN(true)    // false (可以被转化为1)
    

    手动注意一下这里 isNaN()的参数也可以是对象,当传入一个对象的时候会先调用被传入对象的valueOf()方法,然后确定该方法返回的数值是否可以被转化为数值。如果不能,再调用对象的toString()方法,再测试返回值是否可以被转化为数值。之所以特别注意这里因为一般JavaScript中的内置函数和操作符都是按照这个流程执行的。下面基于isNaN举个栗子:

    1
    2
    3
    4
    5
    6
    
    var a = {};
    isNaN(a);      // true 
    //执行过程
    a.valueOf()    // {},不能转化。
    //然后执行
    a.toString()   // 返回"[object Object]" 也不能被转化,所以isNaN返回true
    

    说到number类型肯定要提一下3个函数:Number(),parseInt(),parseFloat().功能相似但也不是完全相同,一个一个来说。 首先Number()可以用于任何数据类型,另外两个则是专门用于把字符串转换成数值。 Number()函数的转换规则:

  • 如果是Boolean值,truefalse将分别被转换为10
  • 如果是数字值则是简单的传入和返回
  • 如果是null,返回0
  • 如果是undefined,返回NaN
  • 如果是字符串,遵循以下规则:
    • 如果字符串中只包含数字(包括前面带正负号),则转换为十进制数字(0开头会忽略0),浮点数转换为浮点数
    • 如果字符串中包含有效的十六进制数,则转换为相同大小的十进制数
    • 如果是空字符串,则返回0
    • 如果字符串中包含除了上述之外的字符,则返回NaN
  • 如果是对象,则调用valueOf()方法,按照上面的规则调用转换返回值,如果返回NaN,则继续调用toString()方法,再次按照上面的规则转换 举几个例子:
    1
    2
    3
    4
    
    var num1 = Number('Hello world') // NaN
    var num2 = Number('') // 0
    var num3 = Number('0000000000020') // 20
    var num4 = Number(true) // 1
    

    再次手动注意一下 +操作符与Number()函数相同 ,如下例:

    1
    2
    
    var str = '1212' 
    +str // 1212
    

    parseInt()只转换字符串,规则大体可以整理为一下几种:

  • 它会忽略字符串前面的空格,如果第一个非空格字符串不是数字或者正负号就会返回NaN
  • 空字符串返回NaNNumber()返回0
  • 按顺序解析每一个字符直至遇到非数字字符或结尾
  • 浮点数会转换为整数
  • 可以添加第二个参数作为转换基数(即多少进制),如果不填第二个参数ES5之后无法解析8进制数会直接忽略前导0
  • 若第二个参数为16可忽略前导0x

🌰:

1
2
3
4
5
6
7
var num1 = parseInt('1111cc') // 1111
var num2 = parseInt('') // NaN
var num3 = parseInt('0xA') // 10
var num4 = parseInt('11.1') // 11
var num5 = parseInt('070') // 70
var num6 = parseInt('AF',16) // 175
var num7 = parseInt('AF') // NaN (未指定16进制且未带前导0x)

为了避免错误解析,建议使用此函数时带着第二个参数 parseFloat()的用法跟parseInt差不多,区别有一下几点:

  • 没有第二个参数(只解析十进制数)
  • 只识别第一个小数点
  • 始终忽略前导0

🌰:

1
2
3
4
5
var num1 = parseFloat('1111cc') // 1111
var num2 = parseInt('0xA') // 0
var num3 = parseInt('11.1') // 11.1
var num4 = parseInt('11.1.11') // 11.1
var num5 = parseInt('011.1') // 11.1

String类型

以单引号或者双引号开头结尾表示 特点: ** 字符串是不可变的,也就是说,字符串一旦创建它的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值得字符串填充该变量 ** 字符串有length属性,但是如果字符串中如果包括以十六进制表示Unicode字符\unnn这种格式的字符在length里算一个长度,这时length返回的就不是精确的字符数目了 转换字符串的方法:

  • toString(): 数值、布尔值、对象和字符串都有toString()方法,注意的是nullundefined没有这个方法,换言之toString()无法将nullundefined转换为字符串,当数值调用toString()时可传入参数2,8,10……等数字的转换基数(进制数)默认为10
  • String() 可将任何类型转换为字符串。执行规则:如果值有toString()方法则调用该方法并返回对应的值(没有参数),null返回"null" undefined返回""undefined 小技巧: 待转换的值+ ""可转换为字符串

    Object类型

    是一组数据和功能的集合。可以通过new操作符后跟要穿件的对象类型名称来创建。创建Object类型的实例并为其添加属性、方法,就可以创建自定义对象。 Object类型是所有实例的基础从继承的角度来讲就是祖宗。 Object的每个实例都有下列属性和方法:

  • constructor: 保存着用于创建当前对象的函数(构造函数)
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象属性中是否存在(不是在实例的原型中)。propertyName必须以字符串形式指定
  • isPrototypeOf(Object): 用于检查传入的对象是否是当前对象的原型
  • propertyIsEnumerable(propertyName): 用于检查给定属性是否能使用 for-in 语句来枚举
  • toLocaleString(): 返回对象的字符串表示,该字符串与执行环境的地区对应(例如,如果是Date类型则返回的数据中与地区相关,在中国返回的格式是"2019/7/27 下午8:12:23")
  • toString(): 返回对象的字符串表示
  • valueOf(): 返回对象的字符串、数值或布尔值表示。

Symbol

ES6 增加了一个新的基本数据类型 symbol. 不过,和其他基本数据类型相比,它有点与众不同,因为它没有字面量的表现形式,而且创建的方式也有点奇怪,只能通过调用全局函数Symbol()来完成。

使用Symbol时注意:

  • symbol可以转化为字符串(两种方式,前面已经介绍了。),可以转换为boolean,但是不能转化为Number
  • 使用Symbol()时最好为其传入参数,容易区分;由于symbol的值是独一无二的,即使是传入相同的参数,二者的值也是不等的。
  • 作为属性名时不能通过.调用需用[]

🌰:

1
2
3
4
5
6
7
8
9
10
11
12
13
let symbol1 = Symbol('a');
let symbol2 = Symbol('a');

let obj = {
    [symbol1]: '噫呜呜噫',
    [symbol2]: '哦哦哦哈哈哈哈'
}
console.log(symbol1 === symbol2) // false
console.log(obj.symbol1)  // undefined
console.log(obj[symbol1]) // 噫呜呜噫
symbol1.toString() // "Symbol('a')"
Number(symbol1) // Uncaught TypeError: Cannot convert a Symbol value to a number
Boolean(symbol1) // true

symbol要细说完全可以但拉出来一篇文章来说了,所以这里简单介绍一下最基本的用法,后续如果写的话,我会在这里添加链接 放纵了好长一段时间了,之前的计划搁置了许久,现在开始重启。各位老铁共同进步,共勉。