【高级程序设计(第四版)】 - 数据类型

227 阅读7分钟

MDN-JavaScript数据类型
JavaScript中有6种简单数据类型(原始类型、原始值):Undefined、Null、Boolean、Number、String和Symbol,一中复杂数据类型Object

检测操作符typeof

  JavaScript一种松散型的语言,变量只是存储值的占位符,其对应的值是可以随便改变的。所以需要一种手段来确定任意变量值的数据类型。typeof操作符返回的结果是字符串:

  • 'undefined'表示值未定义(变量声明未赋值或未声明变量均返回undefined)
  • "boolean"表示值为布尔值
  • "string"表示值为字符串
  • "number"表示值为数值
  • "symbol"表示值为符号
  • "function"表示值为函数
  • "object"表示值为对象(不是函数)或null(空指针对象)

简单数据类型

Undefined类型

  Undefined类型只有一个值,特殊值undefined。当使用var或let声明变量但是未初始化时则默认给变量赋予了undefined值

undefined是由null派生而来,在非严格模式下两者相等

  let message;
  // let age;
  console.log(typeof message); // "undefined"
  console.log(typeof age); // "undefined"
  // 虽然未初始化和未定义变量使用`typeof`的返回值都是undefined,但是本质上还是有区别的
  console.log(message); // undefined
  console.log(age); // ReferenceError: age is not defined
  console.log(undefined == null); // true

Null类型

  Null类型同样只有一个值,即特殊值null。逻辑上讲,null值表示一个空指针对象。这也是typeof操作符返回"object"的原因

	console.log(typeof null); // "object"

Boolean类型

  Boolean类型有两个字面量值: truefalse。布尔值变量字面量true和false严格区分大小写,其他大小写混写形式都是有效标识符,但不是布尔值。 在if条件语句其他流程控制语句中,其他类型会被隐式调用Boolean()(基本包装类型) 函数将其转换为布尔值,不同类型的转换规则:

数据类型true值false值
String非空字符串空字符串""
Number非零数值(包含无穷值)0,NaN
Object任意对象([]、{}等)null
Undefined——undefined
let isTrue = True; // ReferenceError: True is not defined
let isFalse = false;
console.log(typeof isFalse); // "boolean"
const emptyString = '';
console.log('emptyString', Boolean(emptyString)); // false
console.log('NaN', Boolean(NaN),  'null', Boolean(null)); // false
console.log('对象', Boolean({}), '非零数值', Boolean(Infinity), '非空字符串', Boolean('0')); // true

Number类型

  • 进制   不同数值类型相应的有不同的数值字面量格式:十进制、八进制(0开头)、十六进制(0x开头)

  • 浮点数

    • 浮点数的精确度最高达到17位小数,浮点数小数点后最少要有一位非0的数字
    • 缺点: 存在舍入误差;无法测试特定浮点数值
  • 值的范围

    • 最大值:Number.MAX_VALUE|,最小值:Number.MIN_VALUE
    • 超出范围的值: 正无穷InfinityNumber.POSITIVE_INFINITY)、负无穷-Infinity(Number.NEGATIVE_INFINITY)
    • 检测方法:isFinite() 返回值:合法范围值为true,超出范围值为false
  • NaN

    • 任何涉及NaN的操作都会返回NaN,NaN与任何值都不相等,包括其自身
    • 检测方法: isNaN- 检测是否可转换为数值,返回值: 可以转换为false 不可以转换为true
  • 数值转换方法

    • Number()(基本包装类型)
      • 布尔值: true转换为1, false转换为0
      • 数值: 直接返回
      • null: 返回0
      • undefined:返回NaN
      • 字符串:
        • 如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number("1")返回 1,Number("123")返回 123,Number("011")返回 11(忽略前面的零)。
        • 如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。
        • 如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。
        • 如果是空字符串(不包含字符),则返回 0。
        • 含除上述情况之外的其他字符,则返回 NaN。
        • 对象:调用 valueOf()方法,并按照上述规则转换返回的值。如果转换结果是 NaN,则调用toString()方法,再按照转换字符串的规则转换。toString()方法,再按照转换字符串的规则转换。
      let num1 = Number("Hello world!"); // NaN 
      let num2 = Number(""); // 0 
      let num3 = Number("000011"); // 11 
      let num4 = Number(true); // 1
    
    • parseInt(string, radix)

    忽略前置空格,直到找到第一个非空格字符, 第一个字符不是数组或符号则返回NaN,如果数字字符 则解析到遇到非数字字符截止

      let num1 = parseInt("1234blue"); // 1234 
      let num2 = parseInt(""); // NaN 
      let num3 = parseInt("0xA"); // 10,解释为十六进制整数
      let num4 = parseInt(22.5); // 22 
      let num5 = parseInt("70"); // 70,解释为十进制值
      let num6 = parseInt("0xf"); // 15,解释为十六进制整数
      // 传入第二个参数
      let num1 = parseInt("10", 2); // 2,按二进制解析
      let num2 = parseInt("10", 8); // 8,按八进制解析
      let num3 = parseInt("10", 10); // 10,按十进制解析
      let num4 = parseInt("10", 16); // 16,按十六进制解析
    
    • parseFloat(string)

    从字符串开头开始检测,解析到字符串末尾或者解析到一个无效的浮点数值为止。parseFloat()始终忽略开头的0,如果字符串表示整数,则parseFloat()返回整数

      let num1 = parseFloat("1234blue"); // 1234,按整数解析
      let num2 = parseFloat("0xA"); // 0 
      let num3 = parseFloat("22.5"); // 22.5 
      let num4 = parseFloat("22.34.5"); // 22.34 
      let num5 = parseFloat("0908.5"); // 908.5 
      let num6 = parseFloat("3.125e7"); // 31250000
    

String类型

字符串特点 字符串是不可变得:一旦创建它们的值就不能变了,要修改某个变量中的字符串值必须先销毁原始字符串,然后将新的字符串保存到该变量 字符串转换方法

  • toString(): toString()方法可见于数值、布尔值、对象和字符串值。
  • String()
    • 如果值有toString()方法,则调用该方法(不传参数)并返回结果
    • 如果值是null(无toString()方法),则返回"null"
    • 如果值是undefined(无toString()方法),则返回"undefined"
 let value1 = 10; 
 let value2 = true; 
 let value3 = null; 
 let value4; 
 console.log(String(value1)); // "10" 
 console.log(String(value2)); // "true" 
 console.log(String(value3)); // "null" 
 console.log(String(value4)); // "undefined"
  • 模板字面量 模板字面量保留换行符,可以跨行定义字符串。
// 这个模板字面量在换行符之后有 25 个空格符
 let myTemplateLiteral = `first line 
  second line`; 
 console.log(myTemplateLiteral.length); // 47 
 // 这个模板字面量以一个换行符开头
 let secondTemplateLiteral = ` 
 first line 
 second line`; 
 console.log(secondTemplateLiteral[0] === '\n'); // true 
 // 这个模板字面量没有意料之外的字符
 let thirdTemplateLiteral = `first line 
 second line`; 
 console.log(thirdTemplateLiteral); 
 // first line 
 // second line
  • 字符串插值

    模板字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。

    • 字符串插值通过在${}中使用一个 JavaScript 表达式实现:
      let exponent = 'second'; 
      // 以前,字符串插值是这样实现的:
      let interpolatedString = 
       value + ' to the ' + exponent + ' power is ' + (value * value); 
      // 现在,可以用模板字面量这样实现:
      let interpolatedTemplateLiteral = 
       `${ value } to the ${ exponent } power is ${ value * value }`; 
      console.log(interpolatedString); // 5 to the second power is 25 
      console.log(interpolatedTemplateLiteral); // 5 to the second power is 25
    

    所有插入的值都会使用 toString()强制转型为字符串,而且任何 JavaScript 表达式都可以用于插值。

    • 在插值表达式中可以调用函数和方法:
  function capitalize(word) { 
   return `${ word[0].toUpperCase() }${ word.slice(1) }`; 
  } 
  console.log(`${ capitalize('hello') }, ${ capitalize('world') }!`); // Hello, World!

Symbol类型

复杂数据类型

Object类型

Object实例共有的属性和方法:

  • constructor:用于创建当前对象的函数。在前面的例子中,这个属性的值就是 Object() 函数。
  • hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如 o.hasOwnProperty("name"))或符号。
  • isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。(第 8 章将详细介绍原型。)
  • propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用(本章稍后讨论的)for-in 语句枚举。与 hasOwnProperty()一样,属性名必须是字符串。
  • toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象对应的字符串、数值或布尔值表示。通常与 toString()的返回值相同。 数据类型