对象与常用内置 API
这一篇分两块:对象(JS 的核心数据载体,与 Java 的”类”差异很大)和常用内置 API(String、Number/Math、Date、JSON、定时器、console、正则等日常工具箱)。
其中原型与 class、Date 的月份从 0 开始、JSON 序列化的坑是重点差异;Array、Set/Map 的方法已在第 2 篇覆盖,本篇不再重复。
一、对象基础
1. 对象字面量与属性访问
1 2 3 4 5 6 7 8 9
| const user = { name: "Tom", age: 18, "full-name": "Tom Hanks" };
user.name; user["name"]; user["full-name"];
|
与 Java 的差异:Java 要 new 类,JS 直接用 { } 写字面量,且键值可任意类型。
2. 动态增删属性、in 判断
1 2 3
| user.email = "a@b.com"; delete user.age; "name" in user;
|
3. 解构与展开
1 2 3 4 5 6
| const { name, age } = user; const { name: n } = user; const { name, ...rest } = user;
const copy = { ...user }; const merged = { ...a, ...b };
|
4. 方法简写与 this
1 2 3 4 5 6 7
| const obj = { name: "Tom", say() { console.log(this.name); } }; obj.say();
|
二、原型与 class(重点差异)
1. 原型 prototype 概念
JS 对象访问属性时,先找自身,找不到就沿原型链向上找:
1 2 3
| const parent = { greet() { return "hello"; } }; const child = Object.create(parent); child.greet();
|
记忆点:**原型 = 对象的”爹”**,属性查找是”子找不到就找爹”。Java 没有这个概念(Java 是类继承,编译期确定)。
2. class 语法(语法糖)
1 2 3 4 5 6 7 8 9 10 11
| class Person { constructor(name, age) { this.name = name; this.age = age; } say() { console.log(`我叫${this.name}`); } } const p = new Person("Tom", 18); p.say();
|
3. 继承 extends / super
1 2 3 4 5 6
| class Student extends Person { constructor(name, age, grade) { super(name, age); this.grade = grade; } }
|
4. 与 Java class 的本质区别
| 特性 |
Java |
JavaScript |
| 本质 |
真正的类,编译期类型 |
class 是语法糖,底层是原型链 |
| 访问修饰符 |
public/private/protected |
无(ES2022 有 # 私有字段) |
| 方法重载 |
支持 |
不支持 |
| 字段 |
编译期固定 |
可运行时动态增删 |
this |
当前实例 |
运行时动态绑定 |
⚠️ 核心认知:JS 的 class 和 Java 的 class 只是名字相同,机制完全不同。JS 里”继承”的本质是原型链,extends 只是把原型链接起来的语法糖。
三、Object 静态方法
1 2 3 4 5 6 7 8 9 10 11 12
| Object.keys(obj); Object.values(obj); Object.entries(obj);
Object.assign(target, src); const copy = Object.assign({}, obj);
Object.freeze(obj); Object.seal(obj);
obj.hasOwnProperty("name"); Object.hasOwn(obj, "name");
|
四、String 常用方法
1. 查找
1 2 3 4 5
| "hello".indexOf("l"); "hello".lastIndexOf("l"); "hello".includes("ell"); "hello".startsWith("he"); "hello".endsWith("lo");
|
2. 截取(slice / substring / substr 的区别)
1 2 3
| "hello".slice(1, 3); "hello".substring(1, 3); "hello".substr(1, 3);
|
⚠️ 坑点:slice(start, end) 和 substring(start, end) 都是”前闭后开”,但 slice 支持负数、substring 不支持;substr(start, 长度) 第二个参数是长度不是结束位置,且已废弃。
3. 转换
1 2 3 4 5 6 7 8 9 10
| "Hello".toUpperCase(); "Hello".toLowerCase(); " hi ".trim(); " hi".trimStart(); "hi ".trimEnd();
"hello world".replace("o", "0"); "hello world".replaceAll("o", "0"); "a,b,c".split(","); "hello".charAt(1);
|
4. 补全 / 重复
1 2 3 4
| "5".padStart(3, "0"); "5".padEnd(3, "0"); "ab".repeat(3); "a".concat("b");
|
五、Number / Math
1. Number
1 2 3 4 5 6 7
| parseInt("12px"); parseFloat("3.14"); (3.14159).toFixed(2);
Number.isInteger(3); Number.isNaN(NaN); Number.isFinite(1 / 0);
|
⚠️ 全局 isNaN("abc") 会先转换再判断(返回 true),Number.isNaN("abc") 不转换(返回 false)。推荐用 Number.isNaN。
2. Math
1 2 3 4 5 6 7 8 9 10
| Math.abs(-5); Math.ceil(3.1); Math.floor(3.9); Math.round(3.5); Math.trunc(3.9); Math.max(1, 2, 3); Math.min(1, 2, 3); Math.random(); Math.pow(2, 10); Math.sqrt(16);
|
随机整数(常用套路):
1 2
| Math.floor(Math.random() * 10); Math.floor(Math.random() * 10) + 1;
|
六、Date(坑最多)
1. 创建
1 2 3 4
| new Date(); new Date(0); new Date("2026-09-12"); new Date(2026, 8, 12);
|
2. 获取 / 设置
1 2 3 4 5 6 7 8
| const d = new Date(); d.getFullYear(); d.getMonth(); d.getDate(); d.getDay(); d.getHours(); d.getMinutes(); d.getSeconds();
|
3. 时间戳
1 2
| d.getTime(); Date.now();
|
4. 格式化
1 2
| d.toLocaleString(); d.toISOString();
|
⚠️ Date 最大的坑:getMonth() 和 new Date(年, 月, 日) 的月份都是 0~11,0 表示一月。所以显示月份要 +1,new Date(2026, 8, 12) 是 9 月 12 日。
对比 Java:Java 有 LocalDate(纯日期)、LocalDateTime、Calendar 等分工;JS 的 Date 一个类同时含日期和时间,且没有不可变副本,用起来更容易踩坑。
七、JSON
1. 序列化 / 反序列化
1 2 3 4
| const user = { name: "Tom", age: 18 };
const str = JSON.stringify(user); const obj = JSON.parse(str);
|
对应 Java 的 Jackson / Gson。
2. 坑点
1 2 3 4 5 6 7
| JSON.stringify({ a: undefined, b: () => {}, c: Symbol() });
JSON.stringify({ d: new Date() });
JSON.parse('{"name": "Tom"}');
|
深拷贝技巧(浅拷贝的坑):
1 2
| const obj = { a: { b: 1 } }; const copy = JSON.parse(JSON.stringify(obj));
|
⚠️ 但这种方式会丢失函数、undefined,仅适用于纯数据对象。
八、定时器(异步基础)
1 2 3 4 5 6 7 8 9 10
| setTimeout(() => { console.log("延迟 1 秒执行一次"); }, 1000);
const id = setInterval(() => { console.log("每隔 1 秒执行一次"); }, 1000);
clearTimeout(id); clearInterval(id);
|
setTimeout:延迟执行一次;setInterval:每隔一段时间重复执行。
- 都返回一个 id,用于清除。
- 对应 Java 的
ScheduledExecutorService / Timer。
九、console(调试)
1 2 3 4 5 6 7 8 9 10
| console.log("普通日志"); console.warn("警告"); console.error("错误"); console.info("信息");
console.table([{ a: 1 }, { a: 2 }]); console.time("t"); console.timeEnd("t");
console.dir(obj);
|
对应 Java 的 System.out.println,但功能更丰富。
十、正则 RegExp(简要)
1 2 3 4 5 6
| const re = /\d+/; const re2 = new RegExp("\\d+");
re.test("123"); "a123b".match(/\d+/); "abc123".replace(/\d+/, "#");
|
常用标志:g(全局)、i(忽略大小写)、m(多行)。
正则语法与 Java 高度相似(都是 Perl 风格),Java 程序员可快速上手,本篇只做简要介绍。
十一、其他全局函数
1 2 3 4 5 6
| encodeURIComponent("a b&c"); decodeURIComponent("a%20b%26c");
isNaN("abc"); Number.isNaN("abc"); isFinite(1 / 0);
|
十二、速查表
| 需求 |
写法 |
| 对象字面量 |
{ name: "Tom" } |
| 属性访问 |
obj.name / obj["name"] |
| 判断属性存在 |
"key" in obj |
| 对象解构 |
const { name, age } = obj |
| 对象合并/浅拷贝 |
{ ...a, ...b } / Object.assign({}, obj) |
| 对象键值数组 |
Object.keys/values/entries |
| 冻结对象 |
Object.freeze(obj) |
| 定义类 |
class Person { constructor(){} } |
| 继承 |
class Student extends Person + super() |
| 字符串查找 |
includes / startsWith / indexOf |
| 字符串截取 |
slice(1, 3) |
| 去空格 |
trim() |
| 全部替换 |
replaceAll("o", "0") |
| 拆数组 |
"a,b".split(",") |
| 保留小数 |
(3.14).toFixed(2) |
| 取整 |
Math.floor / Math.ceil / Math.round |
| 随机数 |
Math.random() |
| 当前时间戳 |
Date.now() |
| JSON 序列化 |
JSON.stringify(obj) / JSON.parse(str) |
| 延迟执行 |
setTimeout(fn, 1000) |
| 定时重复 |
setInterval(fn, 1000) |
| 打印日志 |
console.log / console.table |
十三、复习要点
- 对象用字面量创建,属性可动态增删,解构/展开是常用操作。
- 原型是 JS 的”继承”机制:属性查找沿原型链向上;
class 只是语法糖。
- JS 的 class ≠ Java 的 class:无访问修饰符、无重载、this 动态绑定。
Object.assign 和 ... 都是浅拷贝;深拷贝可用 JSON.parse(JSON.stringify(obj))(但丢函数/undefined)。
- String 截取:
slice 支持负数、substr 已废弃;replace 只换第一个、replaceAll 换全部。
toFixed 返回的是字符串;Number.isNaN 比全局 isNaN 更严格。
- Date 月份从 0 开始(
getMonth() 和构造函数的月参数),显示要 +1。
JSON.stringify 会忽略 undefined/函数/Symbol,Date 转 ISO 字符串。
setTimeout 延迟一次、setInterval 定时重复,返回 id 用于清除。
- 忘了某个 API,回本文对应小节查示例即可。
至此,JS 基础五篇(字面量与变量/数据类型/运算符、流程控制与数组集合、函数、对象与内置 API)已全部完成,覆盖了从入门到进阶的核心知识点,可配合复习速查表使用。