首页 > 编程语言 >JavaScript从零学起 —— 数据类型(进阶篇6)

JavaScript从零学起 —— 数据类型(进阶篇6)

时间:2024-10-22 13:20:54浏览次数:3  
标签:const log 匹配 数据类型 Date 进阶篇 new 零学起 console

说明:此文章用作个人学习记录,若有任何问题或建议欢迎大家在评论区讨论

文章目录


前言

在前面的学习中,我们已经深入了解了对象 (Object)、数组 (Array)、和函数 (function)
这三种最常用的引用类型

本文作为 JavaScript 数据类型的最后一篇,
我们将详细探讨日期 (Date)、正则表达式 (RegExp)、错误对象 (Error)
以及 ES6 引入的新类型:MapSetWeakMapWeakSet
我们将从它们的定义、实现到常见问题和解决方案,进行全方位的讲解

如果把 JavaScript 比作一个乐高玩具,
那么在完成了所有数据类型的学习后,你就相当于掌握了构建这个乐高玩具的所有零件

下一篇开始,我们将进入控制语句和循环语句的学习,尝试将这些乐高零件组合起来

开始写的时候,真没预计到单是数据类型,就写了1个基础篇+6个进阶篇
只能说是越深入研究,越能发现JavaScript的有趣之处吧


一、日期 (Date)

1. Date 类型的定义

Date 对象是 JavaScript 用来处理日期和时间的内置对象
记录从 1970 年 1 月 1 日 00:00:00 UTC 起到现在的时间点,称为 “Unix 时间戳”

这也是为什么几乎所有电子设备的初始时间都是1970.01.01

通过 Date 对象,我们可以获取当前时间、设定日期、比较日期、计算时间差


2. 创建 Date

  1. 当前时间
    创建一个表示当前日期和时间的 Date 对象
    示例:
    const now = new Date();
    console.log(now); // 输出当前的日期和时间
    

  1. 日期字符串创建
    传入一个日期的字符串,Date 会自动解析并创建一个对应的日期对象
    示例:

    const date = new Date('2024-10-21');
    console.log(date); 
    

    在这里插入图片描述

    日期字符串格式:
    JavaScript能识别多种日期字符串的格式,
    但是推荐只使用一种标准格式,即ISO 8601格式

    • 格式:YYYY-MM-DDTHH:mm:ss.sssZ
    • YYYY:年(四位数)
    • MM:月(01 到 12)
    • DD:日(01 到 31)
    • T:日期和时间的分隔符
    • HH:mm:ss.sss:时间部分

    示例:

    const date = new Date('2024-10-21T15:30:00+08:00'); //北京时间是在+8时区,所以这里+08:00
    console.log(date); 
    

  1. 年、月、日创建
    格式:new Date(year, month, day, hours, minutes, seconds, milliseconds)
    未指定的部分会被设为 0

    const sDate = new Date(2024, 9, 21); // 月份从0开始,0代表1月
    console.log(sDate); 
    

    在这里插入图片描述

  2. 时间戳创建
    传入一个数字作为参数,表示从 1970 年 1 月 1 日开始的毫秒数。

    const timestampDate = new Date(0);
    console.log(timestampDate); // 输出: Thu Jan 01 1970 00:00:00 GMT+0000 (UTC)
    

    该方式在日志记录、服务器间的远程交互以及精准时间差计算等场景中非常实用


3. 常用方法

  • 获取日期和时间

    const now = new Date();
    console.log(now.getFullYear()); // 获取年份
    console.log(now.getMonth());    // 获取月份(0-11,0表示1月)
    console.log(now.getDate());     // 获取日期(1-31)
    console.log(now.getDay());      // 获取星期几(0-6,0表示周日)
    console.log(now.getHours());    // 获取小时(0-23)
    console.log(now.getMinutes());  // 获取分钟(0-59)
    console.log(now.getSeconds());  // 获取秒数(0-59)
    
  • 设置日期和时间

    const myDate = new Date();
    myDate.setFullYear(2025); // 设置年份为 2025
    myDate.setMonth(5);       // 设置月份为 6月
    myDate.setDate(15);       // 设置日期为 15日
    

4. 日期格式化

JavaScript 中的 Date 对象自带的方法对于日期格式化相对有限
通常,我们会使用手动拼接或借助库(如 moment.js 或现代的 Intl.DateTimeFormat API)来格式化日期

示例:

const date = new Date();
const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
console.log(formattedDate); // 输出: 2024-10-20

5. 常见问题与解决方案

  1. 月份从 0 开始问题

    • Date 对象中,月份是从 0 到 11 的值,0 表示 1 月,11 表示 12 月
      所以格式化日期的时候,要记得在月份的数字上+1
  2. 时区问题

    • 问题描述:Date 对象默认使用系统的本地时区,

    • 然而作为系统中的统一时间标准。无论服务器、客户端还是数据库
      所有时间都应该是使用 UTC 时间,然后根据需要转换为本地时间

    • 解决方法:

      UTC 方法

      使用 getUTCDate()getUTCMonth()getUTCFullYear() 方法获取 UTC 时间

      const localDate = new Date();
      console.log('本地时间:', localDate); // 本地时间
      
      // 获取 UTC 时间
      const utcYear = localDate.getUTCFullYear();
      const utcMonth = (localDate.getUTCMonth() + 1).toString().padStart(2, '0'); // 月份从0开始
      const utcDate = localDate.getUTCDate().toString().padStart(2, '0');
      
      const formattedUTCDate = `${utcYear}-${utcMonth}-${utcDate}`;
      console.log('UTC 时间:', formattedUTCDate); // 输出 UTC 时间
      

      使用 toISOString()

      toISOString() 方法可以返回一个 ISO 格式的字符串,表示 UTC 时间

      const date = new Date();
      const isoString = date.toISOString();
      console.log('ISO 格式 UTC 时间:', isoString); // 例如:2024-10-20T15:30:00.000Z
      

      使用第三方库

      Moment.jsdate-fns都是和时间操作有关的第三方库,以后有时间详细说说 先挖个坑

3. 如何判断闰年

  • 被4整除的并且不被100整除的年份
  • 能够被400整除的年份

示例:

function runYear(year) {
    return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
console.log(runYear(2024)); // 输出: true
console.log(runYear(2023)); // 输出: false

二、正则表达式 (RegExp)

1. 正则表达式的定义

正则表达式是一种用于匹配文本模式的表达式
它可以用来验证输入、查找和替换文本、提取信息


2. 创建正则表达式

  1. 使用字面量创建

    const regex = /hello/;
    
  2. 使用 RegExp 构造函数

    const regex = new RegExp('hello');
    

3. 匹配常用字符

正则表达式中定义匹配规则的常用字符:

  • .: 匹配除换行符以外的任意字符
  • \d: 匹配一个数字(0-9)
  • \D: 匹配一个非数字字符
  • \w: 匹配一个字母、数字或下划线字符
  • \W: 匹配一个非字母、非数字、非下划线字符
  • \s: 匹配空白字符(空格、制表符等)
  • \S: 匹配非空白字符
  • ^: 匹配字符串的开头
  • $: 匹配字符串的结尾
  • *: 匹配前面的子表达式零次或多次
  • +: 匹配前面的子表达式一次或多次
  • ?: 匹配前面的子表达式零次或一次
  • {n,m}: 匹配前面的子表达式至少 n 次,至多 m 次

4. 常用方法

  • test(): 测试字符串是否匹配正则表达式,返回 truefalse

    const regex = /hello/;
    console.log(regex.test('hello world')); // 输出: true
    console.log(regex.test('hi there'));    // 输出: false
    
  • match(): 在字符串中查找匹配项,返回一个数组

    const str = 'hello world';
    const result = str.match(/hello/);
    console.log(result); // 输出: ['hello']
    
  • replace(): 替换匹配的子字符串

    const str = 'hello world';
    const newStr = str.replace(/world/, 'JavaScript');
    console.log(newStr); // 输出: 'hello JavaScript'
    
  • split(): 使用正则表达式分割字符串

    const str = 'apple, banana, cherry';
    const fruits = str.split(/, /);
    console.log(fruits); // 输出: ['apple', 'banana', 'cherry']
    

5. 正则表达式中的标志(Flags)

  • g: 全局匹配(查找所有匹配项,而不是找到第一个就停止)
  • i: 不区分大小写匹配
  • m: 多行匹配
  • s: 允许 . 匹配换行符
  • u: 支持 Unicode
  • y: 粘性匹配,从目标字符串的当前位置开始匹配

示例:

const regex = /hello/gi; // 匹配所有不区分大小写的 'hello'
console.log('Hello hello HEllO'.match(regex)); // 输出: ['Hello', 'hello', 'HEllO']

6. 常见问题与解决方案

1. 贪婪匹配与惰性匹配

  • 问题描述:正则表达式默认使用贪婪匹配,
    贪婪匹配会尽可能多的匹配字符,而有的时候我们仅需要惰性匹配,只匹配最小范围即可
  • 解决方案:使用 ? 将匹配变为惰性匹配。
const str = '123abc456';
console.log(str.match(/\d+/));    // 输出: ['123456'] (贪婪匹配)
console.log(str.match(/\d+?/));   // 输出: ['1'] (惰性匹配)

2. 转义字符

  • 问题描述:特殊字符(比如 .* 等),需要使用反斜杠 \ 进行转义
  • 解决方案:在需要匹配这些特殊字符时,用 \ 进行转义
const str = '3.14';
const regex = /\./;		// 定义一个正则表达式变量 ,用于匹配 '.' 
console.log(regex.test(str)); // 匹配到了,输出: true

3. 跨行匹配

  • 问题描述:默认情况正则表达式不会匹配换行符。
  • 解决方案:使用 s 标志来匹配换行符。
const str = 'hello\nworld';
const regex = /hello.world/s;
console.log(regex.test(str)); // 输出: true

三、错误对象 (Error)

1. 错误对象的定义

当程序运行时遇到错误,JavaScript 会创建一个错误对象,并停止当前代码的执行


2. 创建错误对象

2.1 使用 Error 构造函数

const error = new Error('错误信息');
console.log(error.name); // 输出: Error
console.log(error.message); // 输出: 错误信息

2.2 错误对象的分类

  • SyntaxError:语法错误
  • ReferenceError:引用未定义的变量
  • TypeError:数据类型不匹配
  • RangeError:数值超出范围
  • URIError:URI 处理函数使用不当
  • EvalError:与 eval() 函数相关的问题(很少使用)

示例:

const typeError = new TypeError('数据类型错误');
console.log(typeError.name); // 输出: TypeError
console.log(typeError.message); // 输出: 数据类型错误

3. try…catch 语句

为了处理代码中的错误,我们可以使用 try...catch 语句
try 中的代码会被正常执行,如果遇到错误自动转换到 catch

示例:

try {
    // 可能会产生错误的代码
    let result = someUndefinedFunction();
} catch (error) {
    // 捕获并处理错误
    console.log('发生错误:', error.message);
}

4. finally

try...catch 语句中,我们可以添加一个 finally
无论是否发生错误,finally 块中的代码都会被执行,用于释放资源

示例:

try {
    console.log('执行');
    throw new Error('错误');
} catch (error) {
    console.log('捕获到错误:', error.message);
} finally {
    console.log('无论如何都会执行的代码');
}

5. 自定义错误

在实际编程中,有的时候需要抛出自定义的错误
可以通过 throw 关键字抛出一个错误对象,抛出自己定义的错误类型。

示例:

function checkNumber(num) {
    if (typeof num !== 'number') {
        throw new TypeError('传入的参数必须是数字');
    }
    console.log('参数是一个数字');
}

try {
    checkNumber('abc'); // 传入非数字,触发错误
} catch (error) {
    console.log('错误信息:', error.message); // 输出: 错误信息: 传入的参数必须是数字
}

6. 错误类型及应用场景

以下是一些常见的错误类型以及它们的应用场景:

  1. SyntaxError(语法错误)

    try {
        eval('console.log("Hello World)'); // 引号缺失,语法错误
    } catch (e) {
        console.log('语法错误:', e.message);
    }
    
  2. ReferenceError(引用错误):尝试引用未定义的变量

    try {
        console.log(undefinedVariable); // 变量未定义
    } catch (e) {
        console.log('引用错误:', e.message);
    }
    
  3. TypeError(类型错误):在不正确的数据类型上执行操作

    try {
        null.someMethod(); // null 上调用方法会引发类型错误
    } catch (e) {
        console.log('类型错误:', e.message);
    }
    
  4. RangeError(范围错误):数值超出了允许范围

    try {
        new Array(-1); // 数组长度不能为负数
    } catch (e) {
        console.log('范围错误:', e.message);
    }
    
  5. URIError(URI 处理错误):错误使用 URI 函数

    try {
        decodeURIComponent('%'); // 无效的 URI 字符
    } catch (e) {
        console.log('URI 错误:', e.message);
    }
    

拓展阅读:Map / Set

MapSet 是 ES6 中的新特性,
用于处理集合类的数据结构,功能比传统的对象和数组更多


1. Map 数据类型

Map 是一个键值对集合,与普通对象不同的是
Map 允许任何类型的值(对象、原始类型)作为键


1.1 Map 创建
可以使用 new Map() 创建一个新的 Map 对象:

const map = new Map();

1.2 操作 Map

  • 添加键值对: 使用 set 方法。

    map.set('name', 'Alice');
    map.set(42, 'The answer');
    map.set(true, 'Yes');
    
  • 获取值: 使用 get 方法。

    console.log(map.get('name')); // 输出: Alice
    console.log(map.get(42));     // 输出: The answer
    
  • 检查键是否存在: 使用 has 方法。

    console.log(map.has('name')); // 输出: true
    console.log(map.has('age'));  // 输出: false
    
  • 删除键值对: 使用 delete 方法。

    map.delete(42);
    console.log(map.has(42)); // 输出: false
    
  • 获取键值对数量: 使用 size 属性。

    console.log(map.size); // 输出: 2
    
  • 清空所有键值对: 使用 clear 方法。

    map.clear();
    console.log(map.size); // 输出: 0
    

1.3 Map 的应用场景

  • 需要使用复杂类型(比如对象)作为键的时候
  • 需要保证键的顺序(Map 会按插入顺序保持键值对)
  • 需要频繁地查询、更新、删除键值对时,Map 比普通对象性能更好

2. Set 数据类型

Set 是一种无重复值的集合
它允许存储任何类型的唯一值(原始值或对象引用)


2.1 Set 创建
可以使用 new Set() 创建一个新的 Set 对象:

const set = new Set();

2.2 操作 Set

  • 添加值: 使用 add 方法

    set.add(1);
    set.add(2);
    set.add(2); // 重复值不会被添加
    set.add('Hello');
    
  • 检查值是否存在: 使用 has 方法

    console.log(set.has(2));    // 输出: true
    console.log(set.has(3));    // 输出: false
    
  • 删除值: 使用 delete 方法

    set.delete(1);
    console.log(set.has(1)); // 输出: false
    
  • 获取元素数量: 使用 size 属性

    console.log(set.size); // 输出: 2
    
  • 清空所有值: 使用 clear 方法

    set.clear();
    console.log(set.size); // 输出: 0
    

2.3 Set 的应用场景

  • 去重操作:将数组中的重复元素移除。
    const numbers = [1, 2, 2, 3, 4, 4, 5];
    const uniqueNumbers = [...new Set(numbers)];
    console.log(uniqueNumbers); // 输出: [1, 2, 3, 4, 5]
    

3. Map 和 Set 的区别

特性MapSet
数据结构键值对集合唯一值集合
数据存储存储键值对,每个键是唯一的仅存储值,所有值都是唯一的
键类型允许任何类型(对象、基本类型)作为键不需要键,直接存储唯一值
常见用途高效键值对存储和查找数据去重、检查唯一值集合

4. WeakMap 和 WeakSet

  • WeakMapMap 类似,但键必须是对象,且对象引用是弱引用
  • WeakSetSet 类似,但只能存储对象,且对象引用是弱引用

4.1 强引用和弱引用:

强引用会阻止垃圾回收,而弱引用不会

简单来说,如果一个对象被强引用指向了,对象所属的内存就会一直保留
反过来说,如果一个对象只被弱引用指向,那么该对象所属的内存就会被定期清理


4.2 WeakMap 和 WeakSet 的使用场景

这两个数据类型可以有效地管理内存

特别是在处理大量对象的时候,弱引用能减少不必要的内存占用

可以在一些临时储存或者跟踪对象的时候使用


标签:const,log,匹配,数据类型,Date,进阶篇,new,零学起,console
From: https://blog.csdn.net/2401_87242367/article/details/143109634

相关文章

  • 用人话讲计算机:小白版Python篇!(二)基本数据类型1和进制数
    一、数据类型上一节我们曾讲到a=1,b=2,c=“b”之类的东西,我们知道a,b,c叫做变量,而现在所谓的数据类型,其实就是1,2,“b”他们分别属于什么。而我们将数据们分为以下几个类型:1、整数整数,就是我们日常生活中的整数,如1,2,3,-1,-2,0,10,90之类。定义方式:a=12、浮点数浮点数,就是小数,如1......
  • 基本数据类型及其使用
    一.整型数据类型  //java的整型数据类型默认为int,1字节=8比特//在申明long类型变量是要在后面跟L或l的后缀 二.表数范围的记忆技巧:①.指数n=(字节数×比特)/2 ②.左不减右减一左边公式=-(2**n)右边公式=2**n-1 三.浮点型数据(由于float的精度差,一般不用) //在申明floa......
  • [SAP ABAP] SE11定义数据类型(结构与表类型)
    1.定义结构使用事务码SE11创建数据类型(结构),输入自定义的数据类型名称,点击创建按钮勾选结构并点击确定按钮 填写简短描述,并在"组件"页签上添加相关字段信息,点击激活按钮即可生效该结构ZSPO_HEADER_4372.定义表类型在定义表类型之前,我们先使用事务码SE11定义结构勾......
  • 数据类型与变量
    1.字面常量在HelloWorld程序中,System.Out.println("HelloWorld");语句,不论程序何时运行,输出的都是HelloWorld,其实"HelloWorld"就是字面常量。常量即程序运行期间,固定不变的量称为常量,比如:一个礼拜七天,一年12个月等。publicclassDemo{  publicstaticvoidmain(......
  • 三,Java编程基础:深入理解数据类型与类型转换
    数据类型与类型转换在Java编程中,数据类型是定义变量存储数据的格式。Java是一种强类型语言,这意味着每个变量和表达式都有一个明确的数据类型。本文将深入探讨Java中的基本数据类型、引用数据类型以及类型转换,包括详细的示例和代码。基本数据类型Java的基本数据类型分为整数类型......
  • JavaScript 的基础语法和数据类型的概述
    JavaScript是一种广泛使用的编程语言,主要用于Web开发。它拥有简洁的语法和丰富的功能。以下是JavaScript的基础语法和数据类型的概述。基础语法变量声明使用var、let或const关键字声明变量。varname="Alice";letage=25;constpi=3.14;数据类型J......
  • Task03:数据类型和操作 Data Types and Opeartors
    Python数据类型与表达式:数据转换视角下的高效编程策略一、引言1.1研究背景在当今的编程领域,Python以其简洁性、易读性和强大的功能而备受青睐。Python数据类型与表达式在编程中具有至关重要的地位。Python的数据类型丰富多样,包括整型、浮点型、布尔型、None类型以及......
  • P2-3与P2-4.【基本数据类型、运算符和表达式】第三节与第四节
    讲解视频:P2-3.【基本数据类型、运算符和表达式】第三节P2-4.【基本数据类型、运算符和表达式】第四节目录必备知识与理论任务实施必备知识与理论C语言中把除了控制语句和输入输出以外的几乎所有的基本操作都作为运算符处理。其运算符和表达式数量之多,在高级......
  • 我在创建表时,建表语句中不同数据类型字段的排列顺序对性能有影响吗?
    在MySQL或其他数据库管理系统(DBMS)中,字段的排列顺序对表的性能影响并不是非常显著或直接的,但在某些特定情况下,优化字段排列可以带来一些性能或存储效率上的好处。以下是一些需要考虑的因素,尤其是当涉及大量数据和性能优化时。1.数据类型的对齐和存储效率MySQL在存储数据时,试......
  • 我希望gid字段是表的自增主键,数据类型采用8个字节的无符号整形数据,并且我要指定自增的
    Sir,为了将gid字段设置为自增主键并且采用8字节无符号整型数据类型(即BIGINTUNSIGNED),您可以使用MySQL的AUTO_INCREMENT机制,并且可以通过ALTERTABLE来指定自增的初始值。具体实现步骤如下:1.字段定义字段名称:gid数据类型:BIGINTUNSIGNED(8字节无符号整数)自增......