javaScript数据类型基础与特性

64 阅读8分钟

简单数据类型种类

JavaScript中有7种简单数据类型(也称原始数据类型):

Undefined、Null、Boolean、Number、String 、BigInt和Symbol。接下来一一介绍。

typeof操作符

typeof在正常情况下有8种返回结果:

  • "undefined"表示值未定义;
  • "boolean"表示值为布尔值;
  • "string"表示值为字符串;
  • "number"表示值为数值;
  • "object"表示值为对象(而不是函数)或 null;
  • "function"表示值为函数;
  • "symbol"表示值为符号;
  • "bigint"表示值为大整数。

特性:调用typeof null返回的结果是“object”是因为特殊值null被认为是一个对空对象的的引用,而我们大多数情况下都是这么使用的。严格来讲函数应当是object,可是函数也有自己特殊的属性。为此有必要通过typeof来区分两者

Undefined 类型

当生命一个字面量时,引擎给他赋的默认值就是undefined,我们也可以自己赋值undefined。当使用 var 或 let 声明了变量但没有初始化时,就相当于给变量赋予了 undefined 值。

特性:一个从未声明的变量与一个已经声明但从未赋值的变量通过typeof操作符的结果是一样的,这就让人会有误解,所以建议变量声明时就赋值,避免上面的结果产生。

Null 类型

null只有一个值:null。逻辑上讲,null 值表示一个空对象指针,这也是给typeof 传一个 null 会返回"object"的原因。由于上面的undefined是由null派生而来。所以js解析时将它们定义为表面相等

console.log(null == undefined); // true

注:即使是这样我也永远不建议用==null来用作条件判断,因为上面两个之所以会相等是因为在==时js同时对两个值进行了隐式转换的,这将损耗浏览器的性能 建议:if(x === null || x === undefined)来判断。

Boolean 类型

Boolean有两个字面值:true 和 false。 虽然布尔值只有两个,但所有其他js类型的值都有相应的布尔值的等价。注意是所有! 要将一个其他类型的值转换为布尔值,可以调用特定的 Boolean()转型函数:

let a = 'str';
let b = Boolean(a); // true

下面的特性表需要熟记!不必去找原理!因为这已经是最底层的规则。

数据类型转换为tue的值转换为false的值
Booleantruefalse
String非空字符串""(空字符串)
Number非零数值(包括无穷值)0、NaN
Object任意对象null
Undefined-undefined

Number类型

顾名思义表示数字,不过它不仅仅能表示十进制,其余的也能表示。 整数也可以用八进制(以 8 为基数)或十六进制(以 16 为基数)字面量表示。对于八进制字面量, 第一个数字必须是零(0),然后是相应的八进制数字(数值 0~7)。如果字面量中包含的数字超出了应 有的范围,就会忽略前缀的零,后面的数字序列会被当成十进制数。

数据处理的一些方法:

Math.abs(item)//绝对值
console.log(Math.max(1, 2, 3, 4)); // 4
console.log(Math.min(1, 2, 3, 4, 5)); // 1
// 保证最大值为1时
Math.min(1,x);
// 保证最小值为1时
Math.max(1,x);
// 求随机数
const randomFn = (min, max) => {
  for (let i = 0; i < 100; i++) {
    let res = Math.floor(Math.floor(Math.random() * (max - min + 1))) + min; //右区间闭合时需要+1,否则不需要
    console.log("random", res);
  }
};
// Math.floor 求接近象限内靠左的整数
Math.floor(-1.4// -2
// Math.ceil  求接近象限内靠右的整数
Math.floor(-1.4// -1

值的范围 由于内存的限制,Number 并不支持表示这个世界上的所有数值。Number 可以表示的最小 数值保存在 Number.MIN_VALUE 中,这个值在多数浏览器中是 5e324;可以表示的最大数值保存在 Number.MAX_VALUE 中,这个值在多数浏览器中是 1.797 693 134 862 315 7e+308。如果某个计算得到的 数值结果超出了 Number 可以表示的范围,那么这个数值会被自动转换为一个特殊的 Infinity(无 穷)值。任何无法表示的负数以-Infinity(负无穷大)表示,任何无法表示的正数以 Infinity(正 无穷大)表示。

特性: 有一个特殊的数值叫 NaN,意思是“不是数值”(Not a Number),用于表示本来要返回数值的操作 失败了(而不是抛出错误)。比如,用 0 除任意数值在其他语言中通常都会导致错误,从而中止代码执 行。但在 ECMAScript 中,0、+0 或0 相除会返回 NaN: console.log(0/0); // NaN console.log(-0/+0); // NaN 如果分子是非 0 值,分母是有符号 0 或无符号 0,则会返回 Infinity 或-Infinity: console.log(5/0); // Infinity console.log(5/-0); // -Infinity 需要注意NaN===Nan返回的是false,想要判断一个数是否是NaN得用isNaN(x)加上typeof x === 'number'(因为字符串放到isNaN也是true) 数值转换:

  • 布尔值,true 转换为 1,false 转换为 0。
  • 数值,直接返回。
  • null,返回 0。
  • undefined,返回 NaN。

String 类型

String(字符串)数据类型表示零或多个 16 位 Unicode 字符序列。字符串可以使用双引号(")、

单引号(')或反引号(`)标示,因此下面的代码都是合法的:

let firstName = "John";

let lastName = 'Jacob';

let lastName = `Jingleheimerschmidt`

特点: ECMAScript 中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改 某个变量中的字符串值,必须先销毁原始的字符串。

方法:

  • charAt(index):返回指定位置的字符
  • charCodeAt(index):返回指定位置字符的 Unicode 编码
  • concat(str1, str2, ...):拼接字符串
  • includes(substring):判断是否包含子串
  • indexOf(substring):返回子串首次出现的位置
  • slice(start, end):截取字符串
  • substring(start, end):截取字符串 :在计算时间时补0很有用
  • substr(start, length):截取字符串(已废弃)
  • replace(regexp, newStr):替换字符串
  • split(separator):分割字符串为数组
  • toUpperCase() / toLowerCase():大小写转换
  • trim():去除首尾空格
  • startsWith(str) / endsWith(str):判断开头/结尾

例子:取YYYY-MM-DD的日期:

function getCurrentDate() {
  const date = new Date();
  let year = date.getFullYear()
  let month = '0' + (date.getMonth() + 1)
  let day = '0' + date.getDate()
  month = month.substring(month.length - 2);
  day = day.substring(day.length - 2);
  return `${year}-${month}-${day}`
}

Symbol 类型

Symbol(符号)是 ECMAScript 6 新增的数据类型。符号是原始值,且符号实例是唯一、不可变的。 可以理解为new Symbol产生一个实例,实例为一个永远不可见的永不重复的密码串,所以这个数据类型最适合用于的对象的键,用来确保对象属性使用唯一标识符。

let sym = Symbol();
console.log(typeof sym); // symbol

let genericSymbol = Symbol();
let otherGenericSymbol = Symbol();
let fooSymbol = Symbol('foo');
let otherFooSymbol = Symbol('foo');
console.log(genericSymbol == otherGenericSymbol); // false

console.log(fooSymbol == otherFooSymbol); // false

传入字符串或数字可以作为描述符,但不能通过描述符反向获取Symbol的值。 要重复使用一个符号的值,普通的new行不通,得使用Symbol的静态防范的for。

let fooGlobalSymbol = Symbol.for('foo'); // 创建新符号
let otherFooGlobalSymbol = Symbol.for('foo'); // 重用已有符号
console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true

// 创建全局符号
let s = Symbol.for('foo');
console.log(Symbol.keyFor(s)); // foo,用来查询描述

Object:数组类型以及方法

  • push(item) :在数组末尾添加元素
  • pop() :移除并返回数组最后一个元素
  • shift() :移除并返回数组第一个元素
  • unshift(item) :在数组开头添加元素
  • concat(arr1, arr2, ...) :合并数组,返回新数组
  • join(separator) :将数组元素拼接成字符串
  • slice(start, end) :截取数组的一部分,返回新数组
  • splice(start, deleteCount, ...items) :删除/插入/替换数组元素
  • forEach(callback) :遍历数组,每个元素执行回调
  • map(callback) :返回新数组,每个元素执行回调
  • filter(callback) :返回新数组,保留满足条件的元素
  • reduce(callback, initialValue) :累计处理数组元素,返回最终结果
  • find(callback) :返回第一个满足条件的元素
  • findIndex(callback) :返回第一个满足条件元素的索引
  • some(callback) :判断是否有元素满足条件
  • every(callback) :判断是否所有元素都满足条件
  • sort(compareFunction) :对数组进行排序
  • reverse() :反转数组顺序
  • includes(item) :判断数组是否包含某元素
  • indexOf(item) :返回元素首次出现的索引
  • lastIndexOf(item) :返回元素最后一次出现的索引 应用:
// 手写一个深拷贝,思路:简单类型直接返回,复杂数据类型循环递归
const deepClone = (obj) => {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  if (obj instanceof Date) {
    return new Date(obj)
  }
  if (Array.isArray(obj)) {
    return obj.map(item => {
      return deepClone(item)
    })
  }
  let res = {}
  for (let i in obj) {
    if (obj.hasOwnProperty(i)) {
      res[i] = deepClone(obj[i])
    }
  }
  return res
}

如何判断各个数据类型:

// 辨别常见的数据类型
const getType = (val) => {
  if (val === null) {
    return 'null';
  }
  if (val === undefined) {
    return 'undefined';
  }
  if (typeof val === 'number') {
    if (isNaN(val)) {
      return 'NaN';
    } else {
      return 'number'
    }
  }
  if (Array.isArray(val)) {
    return 'array'
  }
  if (typeof val === 'function') { return 'function' }
  if (typeof val === 'object') { return 'object' }
  if (typeof val === 'string') { return 'string' }
  if (typeof val === 'boolean') { return 'boolean' }
  if (typeof val === 'symbol') { return 'symbol' }
  if (typeof val === 'bigint') { return 'bigint' }
  return 'unknown' //除非js新版本,否则不会是unknown
}