目录
[1. 编程思想对比](#1. 编程思想对比)
[2. 内置构造函数](#2. 内置构造函数)
[3. 数组方法详解](#3. 数组方法详解)
[4. 字符串方法详解](#4. 字符串方法详解)
[5. 复习要点速查表](#5. 复习要点速查表)
本文对比了面向过程与面向对象编程思想,介绍了JavaScript内置对象的核心方法。面向过程强调步骤分解(如制作蛋炒饭流程),性能高但复用性差;面向对象通过对象协作(如厨师与顾客类)实现封装、继承、多态三大特性,更易维护扩展。重点讲解了Object.keys/values/assign、数组四大核心方法(forEach遍历、filter过滤、map转换、reduce计算)以及字符串常用操作(split、substring、includes等),并提供了最佳实践建议:优先使用字面量创建对象,根据场景选择数组方法,保持对象职责单一。最后用口诀总结了面向对象特性和内置对象的核心方法。
1. 编程思想对比
1.1 面向过程编程
把问题分解成一系列步骤,然后按顺序执行这些步骤
// 示例:制作蛋炒饭
function makeEggFriedRice() {
煮饭();
打鸡蛋();
炒鸡蛋();
混合炒();
装盘();
}
// ✅ 优点:性能高,适合硬件操作
// ❌ 缺点:代码复用性差,维护困难
1.2 面向对象编程(OOP)
把问题分解成对象,通过对象之间的协作解决问题
// 示例:制作盖浇饭
class Chef {
cookRice() { /*...*/ }
prepareTopping() { /*...*/ }
combine() { /*...*/ }
}
class Customer {
order() { /*...*/ }
eat() { /*...*/ }
}
// ✅ 优点:易维护、易复用、易扩展
// ❌ 缺点:性能稍低于面向过程
OOP 三大特性
特性 | 说明 | 生活示例 |
---|---|---|
封装 | 隐藏实现细节,暴露接口 | 电视机:用遥控器操作,无需知道内部电路 |
继承 | 子类继承父类特性 | 智能手机继承手机的基本功能 |
多态 | 同一方法不同实现 | 动物叫声:狗"汪汪" vs 猫"喵喵" |
2. 内置构造函数
2.1 Object 对象
静态方法
const person = { name: '小明', age: 18 };
// ✅ Object.keys - 获取所有属性名
const keys = Object.keys(person);
console.log(keys); // ['name', 'age']
// ✅ Object.values - 获取所有属性值
const values = Object.values(person);
console.log(values); // ['小明', 18]
// ✅ Object.assign - 对象合并/拷贝
const newPerson = Object.assign({}, person, { gender: '男' });
console.log(newPerson); // {name: '小明', age: 18, gender: '男'}
// ⚠️ 注意:Object.assign 是浅拷贝
包装类型
// 字符串字面量
const str = 'hello';
// 实际执行过程(JS引擎自动包装)
const temp = new String(str);
console.log(temp.length); // 5
temp = null;
2.2 Array 数组
创建数组
// 使用构造函数(不推荐)
const arr1 = new Array(3, 5); // [3, 5]
// ✅ 推荐:字面量创建
const arr2 = [1, 2, 3];
核心方法
方法 | 作用 | 返回值 | 使用场景 |
---|---|---|---|
forEach |
遍历数组 | undefined | 代替for循环 |
filter |
过滤元素 | 新数组 | 筛选符合条件的元素 |
map |
转换元素 | 新数组 | 数据格式转换 |
reduce |
累计计算 | 累计结果 | 求和/平均值等 |
2.3 String 字符串
创建字符串
// 使用构造函数
const str1 = new String('hello');
// ✅ 推荐:字面量创建
const str2 = 'world';
3. 数组方法详解
3.1 核心方法
forEach - 遍历数组
const colors = ['红色', '绿色', '蓝色'];
colors.forEach(function(color, index) {
console.log(`索引 ${index}: ${color}`);
});
// ✅ 箭头函数简化
colors.forEach((color, index) =>
console.log(`颜色${index + 1}: ${color}`)
);
filter - 过滤数组
const numbers = [10, 20, 30, 40, 50];
// 筛选大于30的数
const bigNumbers = numbers.filter(num => num > 30);
console.log(bigNumbers); // [40, 50]
// 筛选偶数
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [10, 20, 30, 40, 50]
map - 转换数组
const prices = [100, 200, 300];
// 价格打八折
const discounted = prices.map(price => price * 0.8);
console.log(discounted); // [80, 160, 240]
// 转换对象格式
const users = [{name: '小明'}, {name: '小红'}];
const names = users.map(user => user.name);
console.log(names); // ['小明', '小红']
reduce - 累计计算
const cart = [20, 35, 15, 40];
// 求总和(无初始值)
const total = cart.reduce((sum, price) => sum + price);
console.log(total); // 110
// 求平均值(有初始值)
const avg = cart.reduce((sum, price, index, arr) => {
sum += price;
return index === arr.length - 1 ? sum / arr.length : sum;
}, 0);
console.log(avg); // 27.5
reduce 执行过程图解
数组: [10, 20, 30]
无初始值:
第1次: sum=10, current=20 → 30
第2次: sum=30, current=30 → 60
有初始值5:
第1次: sum=5, current=10 → 15
第2次: sum=15, current=20 → 35
第3次: sum=35, current=30 → 65
3.2 其他常用方法
方法 | 示例 | 说明 |
---|---|---|
join |
['a','b'].join('-') → "a-b" |
数组转字符串 |
find |
[5,12,8].find(n => n > 10) → 12 |
找第一个符合条件的元素 |
every |
[2,4,6].every(n => n%2===0) → true |
所有元素都满足条件 |
some |
[1,3,4].some(n => n%2===0) → true |
至少一个元素满足条件 |
concat |
[1,2].concat([3,4]) → [1,2,3,4] |
合并数组 |
sort |
[3,1,2].sort() → [1,2,3] |
排序(默认按字符串) |
splice |
arr.splice(1,2,'a') |
删除/替换元素 |
reverse |
[1,2,3].reverse() → [3,2,1] |
反转数组 |
findIndex |
[5,12,8].findIndex(n => n>10) → 1 |
找第一个符合条件的索引 |
// join 示例
const names = ['小明', '小红', '小刚'];
const nameStr = names.join('、'); // "小明、小红、小刚"
// find 示例
const users = [
{id: 1, name: '小明'},
{id: 2, name: '小红'}
];
const user = users.find(u => u.id === 2); // {id: 2, name: '小红'}
// sort 注意事项
const nums = [10, 5, 40];
nums.sort(); // [10, 40, 5] ❌ 错误(按字符串排序)
nums.sort((a, b) => a - b); // [5, 10, 40] ✅ 正确
4. 字符串方法详解
常用方法
方法 | 示例 | 说明 |
---|---|---|
length |
'hello'.length → 5 |
字符串长度 |
split |
'a-b-c'.split('-') → ['a','b','c'] |
字符串转数组 |
substring |
'hello'.substring(1,3) → "el" |
截取子字符串 |
startsWith |
'hello'.startsWith('he') → true |
是否以...开头 |
includes |
'hello'.includes('ell') → true |
是否包含子串 |
toUpperCase |
'hello'.toUpperCase() → "HELLO" |
转大写 |
toLowerCase |
'HELLO'.toLowerCase() → "hello" |
转小写 |
indexOf |
'hello'.indexOf('l') → 2 |
查找子串位置 |
endsWith |
'hello'.endsWith('lo') → true |
是否以...结尾 |
replace |
'a-b'.replace('-','_') → "a_b" |
替换子串 |
match |
'a1b2'.match(/\d/g) → ['1','2'] |
正则匹配 |
// split 示例
const dateStr = '2023-10-15';
const dateParts = dateStr.split('-'); // ['2023', '10', '15']
// substring 示例
const str = 'JavaScript';
str.substring(0, 4); // "Java"
str.substring(4); // "Script"
// includes 示例
const email = 'user@example.com';
if (email.includes('@')) {
console.log('有效邮箱');
}
// replace 示例
let message = '我喜欢苹果';
message = message.replace('苹果', '香蕉'); // "我喜欢香蕉"
5. 复习要点速查表
面向对象 vs 面向过程
特性 | 面向对象 | 面向过程 |
---|---|---|
核心思想 | 对象协作 | 步骤分解 |
代码复用 | 高(继承) | 低 |
维护难度 | 易 | 难 |
性能 | 稍低 | 高 |
适用场景 | 大型应用 | 硬件操作 |
内置对象方法总结
Object 方法
方法 | 作用 | 返回值 |
---|---|---|
Object.keys() |
获取属性名 | 数组 |
Object.values() |
获取属性值 | 数组 |
Object.assign() |
对象合并 | 新对象 |
Array 核心方法
方法 | 作用 | 返回值 |
---|---|---|
forEach() |
遍历 | undefined |
filter() |
过滤 | 新数组 |
map() |
转换 | 新数组 |
reduce() |
累计 | 计算结果 |
String 常用方法
方法 | 作用 | 返回值 |
---|---|---|
split() |
字符串转数组 | 数组 |
substring() |
截取子串 | 字符串 |
includes() |
检查包含 | 布尔值 |
toUpperCase() |
转大写 | 字符串 |
最佳实践
-
优先使用字面量 :
[]
代替new Array()
,{}
代替new Object()
-
数组方法选择:
-
遍历用
forEach
-
过滤用
filter
-
转换用
map
-
计算用
reduce
-
-
字符串操作:
-
简单替换用
replace
-
检查包含用
includes
-
大小写转换用
toUpperCase/toLowerCase
-
-
面向对象设计:
-
封装相关数据和行为
-
优先组合而非继承
-
保持对象职责单一
-
面试重点记忆口诀 :
"面向对象三特性,封装继承多态行"
"数组方法四金刚,forEach/filter/map/reduce强"
"字符串操作两板斧,split切分substring取"
"对象操作三剑客,keys/values/assign忙"