JavaScript 教程

纯干货教学,从零开始学习 JavaScript

JavaScript 数据类型

JavaScript 是一种动态类型语言,变量的类型在运行时确定。本章节将介绍 JavaScript 的各种数据类型、类型检测和类型转换。

🎯 数据类型的重要性

了解 JavaScript 的数据类型是编写正确、高效代码的基础。不同的数据类型有不同的特性和使用方法,掌握它们可以帮助你避免类型错误,写出更健壮的代码。

JavaScript 的数据类型分类

JavaScript 的数据类型分为两大类:

  1. 原始数据类型:直接存储值
  2. 引用数据类型:存储对值的引用

原始数据类型

JavaScript 有 7 种原始数据类型:

1. String(字符串)

字符串是由零个或多个字符组成的序列:

// 字符串字面量
const str1 = "Hello, World!"; // 使用双引号
const str2 = 'Hello, World!'; // 使用单引号
const str3 = `Hello, World!`; // 使用模板字符串

// 字符串长度
console.log(str1.length); // 13

// 字符串方法
console.log(str1.toUpperCase()); // HELLO, WORLD!
console.log(str1.toLowerCase()); // hello, world!
console.log(str1.substring(0, 5)); // Hello

// 模板字符串
const name = "John";
const greeting = `Hello, ${name}!`;
console.log(greeting); // Hello, John!

2. Number(数字)

数字类型包括整数和浮点数:

// 数字字面量
const num1 = 10; // 整数
const num2 = 3.14; // 浮点数
const num3 = -5; // 负数
const num4 = 0; // 零

// 特殊数字值
const infinity = Infinity; // 无穷大
const negativeInfinity = -Infinity; // 负无穷大
const notANumber = NaN; // 非数字

// 数字方法
console.log(Math.abs(-5)); // 5
console.log(Math.round(3.14)); // 3
console.log(Math.sqrt(16)); // 4
console.log(Math.pow(2, 3)); // 8

3. Boolean(布尔值)

布尔值只有两个值:truefalse

// 布尔字面量
const isTrue = true;
const isFalse = false;

// 布尔表达式
const isGreater = 10 > 5; // true
const isEqual = 10 === 5; // false

// 逻辑运算符
console.log(true && false); // false(与运算)
console.log(true || false); // true(或运算)
console.log(!true); // false(非运算)

4. Undefined(未定义)

undefined 表示变量已声明但未初始化:

// 未初始化的变量
let x;
console.log(x); // undefined

// 函数没有返回值
function myFunction() {
    // 没有 return 语句
}
console.log(myFunction()); // undefined

// 访问不存在的对象属性
const person = {name: "John"};
console.log(person.age); // undefined

5. Null(空值)

null 表示一个空值或不存在的对象:

// null 字面量
const emptyValue = null;

// 表示空对象
const obj = null;

// 区别 undefined 和 null
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"(这是一个历史遗留问题)

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

6. Symbol(符号)

Symbol 是 ES6 中新增的原始数据类型,表示唯一的、不可变的值:

// 创建 Symbol
const sym1 = Symbol();
const sym2 = Symbol("description");

// Symbol 是唯一的
const sym3 = Symbol("key");
const sym4 = Symbol("key");
console.log(sym3 === sym4); // false

// 作为对象属性
const obj = {
    [sym1]: "value"
};
console.log(obj[sym1]); // value

7. BigInt(大整数)

BigInt 是 ES11 中新增的原始数据类型,用于表示任意精度的整数:

// 创建 BigInt
const bigInt1 = 123n; // 使用 n 后缀
const bigInt2 = BigInt(123); // 使用 BigInt() 函数

// 大整数运算
const bigInt3 = 1000000000000000000n;
const bigInt4 = 1n;
console.log(bigInt3 + bigInt4); // 1000000000000000001n

// 注意:BigInt 不能与 Number 直接运算
// console.log(bigInt3 + 1); // 报错

引用数据类型

JavaScript 的引用数据类型包括:

1. Object(对象)

对象是键值对的集合:

// 对象字面量
const person = {
    name: "John",
    age: 30,
    city: "New York"
};

// 访问对象属性
console.log(person.name); // John
console.log(person["age"]); // 30

// 修改对象属性
person.age = 31;
console.log(person.age); // 31

// 添加新属性
person.job = "Engineer";
console.log(person.job); // Engineer

// 删除属性
delete person.city;
console.log(person.city); // undefined

2. Array(数组)

数组是有序的值的集合:

// 数组字面量
const fruits = ["apple", "banana", "orange"];

// 数组长度
console.log(fruits.length); // 3

// 访问数组元素
console.log(fruits[0]); // apple

// 修改数组元素
fruits[1] = "grape";
console.log(fruits[1]); // grape

// 数组方法
fruits.push("mango"); // 添加元素到末尾
console.log(fruits); // ["apple", "grape", "orange", "mango"]

fruits.pop(); // 移除末尾元素
console.log(fruits); // ["apple", "grape", "orange"]

fruits.shift(); // 移除第一个元素
console.log(fruits); // ["grape", "orange"]

fruits.unshift("apple"); // 添加元素到开头
console.log(fruits); // ["apple", "grape", "orange"]

3. Function(函数)

函数是可重复使用的代码块:

// 函数声明
function greet(name) {
    return "Hello, " + name + "!";
}

// 函数表达式
const greetExpression = function(name) {
    return "Hello, " + name + "!";
};

// 箭头函数
const greetArrow = (name) => "Hello, " + name + "!";

// 函数调用
console.log(greet("John")); // Hello, John!
console.log(greetExpression("Jane")); // Hello, Jane!
console.log(greetArrow("Bob")); // Hello, Bob!

4. Date(日期)

Date 对象用于处理日期和时间:

// 创建 Date 对象
const now = new Date();
const specificDate = new Date(2023, 0, 1); // 2023年1月1日
const dateFromString = new Date("2023-01-01");

// 日期方法
console.log(now.getFullYear()); // 当前年份
console.log(now.getMonth()); // 当前月份(0-11)
console.log(now.getDate()); // 当前日期
console.log(now.getHours()); // 当前小时
console.log(now.getMinutes()); // 当前分钟
console.log(now.getSeconds()); // 当前秒数

// 日期格式化
console.log(now.toISOString()); // ISO 格式
console.log(now.toLocaleString()); // 本地格式

5. RegExp(正则表达式)

正则表达式用于匹配字符串中的模式:

// 创建正则表达式
const regex1 = /pattern/; // 字面量形式
const regex2 = new RegExp("pattern"); // 构造函数形式

// 正则表达式标志
const regex3 = /pattern/g; // g - 全局匹配
const regex4 = /pattern/i; // i - 忽略大小写
const regex5 = /pattern/m; // m - 多行匹配

// 正则表达式方法
const text = "Hello, World!";
console.log(/Hello/.test(text)); // true
console.log(/World/.exec(text)); // ["World", index: 7, input: "Hello, World!", groups: undefined]

类型检测

在 JavaScript 中,可以使用以下方法检测变量的类型:

1. typeof 运算符

typeof 运算符返回变量的类型:

console.log(typeof "Hello"); // "string"
console.log(typeof 10); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"(历史遗留问题)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function() {}); // "function"
console.log(typeof Symbol()); // "symbol"
console.log(typeof 123n); // "bigint"

2. instanceof 运算符

instanceof 运算符检查对象是否是某个构造函数的实例:

const arr = [];
const obj = {};
const func = function() {};
const date = new Date();

console.log(arr instanceof Array); // true
console.log(obj instanceof Object); // true
console.log(func instanceof Function); // true
console.log(date instanceof Date); // true

// 注意:instanceof 不能用于原始数据类型
console.log("Hello" instanceof String); // false

3. Array.isArray() 方法

Array.isArray() 方法检查值是否为数组:

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray("Hello")); // false
console.log(Array.isArray(10)); // false

4. Object.prototype.toString.call() 方法

这是最可靠的类型检测方法:

console.log(Object.prototype.toString.call("Hello")); // "[object String]"
console.log(Object.prototype.toString.call(10)); // "[object Number]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call(function() {})); // "[object Function]"
console.log(Object.prototype.toString.call(Symbol())); // "[object Symbol]"
console.log(Object.prototype.toString.call(123n)); // "[object BigInt]"
console.log(Object.prototype.toString.call(new Date())); // "[object Date]"
console.log(Object.prototype.toString.call(/regex/)); // "[object RegExp]"

类型转换

JavaScript 是一种动态类型语言,会自动进行类型转换。你也可以显式地进行类型转换:

1. 自动类型转换

JavaScript 在需要时会自动转换类型:

// 字符串与数字相加(字符串连接)
console.log("5" + 5); // "55"

// 字符串与数字相减(字符串转换为数字)
console.log("10" - 5); // 5

// 布尔值与数字相加(布尔值转换为数字)
console.log(true + 1); // 2
console.log(false + 1); // 1

// 字符串与布尔值相加(布尔值转换为字符串)
console.log("Hello " + true); // "Hello true"

// 非布尔值在布尔上下文中(转换为布尔值)
console.log(Boolean("Hello")); // true
console.log(Boolean("")); // false
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean({})); // true
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false

2. 显式类型转换

你可以使用内置函数显式地转换类型:

// 转换为字符串
const num = 10;
const str1 = String(num);
const str2 = num.toString();
const str3 = num + "";
console.log(str1, str2, str3); // "10", "10", "10"

// 转换为数字
const str = "10";
const num1 = Number(str);
const num2 = parseInt(str);
const num3 = parseFloat(str);
const num4 = +str;
console.log(num1, num2, num3, num4); // 10, 10, 10, 10

// 转换为布尔值
const value = "Hello";
const bool1 = Boolean(value);
const bool2 = !!value;
console.log(bool1, bool2); // true, true

// 转换为对象
const primitive = "Hello";
const obj = Object(primitive);
console.log(obj); // [String: "Hello"]

类型转换的规则

JavaScript 中的类型转换遵循以下规则:

1. 转换为字符串

  • null 转换为 "null"
  • undefined 转换为 "undefined"
  • true 转换为 "true"
  • false 转换为 "false"
  • 数字转换为对应的字符串表示
  • 对象调用 toString() 方法

2. 转换为数字

  • null 转换为 0
  • undefined 转换为 NaN
  • true 转换为 1
  • false 转换为 0
  • 字符串转换为对应的数字,转换失败则为 NaN
  • 对象先转换为字符串,再转换为数字

3. 转换为布尔值

  • 假值(falsy values)转换为 falsefalse0""nullundefinedNaN
  • 其他值转换为 true

💡 学习提示

在 JavaScript 中处理数据类型时,建议:

  • 了解不同数据类型的特点和使用场景
  • 使用适当的类型检测方法
  • 注意自动类型转换可能导致的意外行为
  • 在需要时显式地进行类型转换,提高代码可读性
  • 使用严格相等运算符(===)避免自动类型转换

📝 学习检查

通过本章节的学习,你应该掌握:

  • JavaScript 的 7 种原始数据类型
  • JavaScript 的引用数据类型
  • 不同类型检测方法的使用
  • 自动类型转换的规则
  • 如何进行显式类型转换
  • 假值(falsy values)的概念