当前位置: 首页 > backend >正文

【前端教程】JavaScript 对象与数组操作实战:从基础到优化

在JavaScript编程中,对象和数组是构建复杂应用的基础。本文将通过多个实用案例,从原始实现出发,逐步优化代码,带你掌握对象创建、数组操作、数据遍历等核心技能。每个案例都包含原始代码解析、优化方案及关键知识点说明,帮助你写出更规范、高效的JavaScript代码。

案例1:创建人类对象及方法实现

需求说明

创建一个包含编号、名称、年龄、性别属性的人类对象,添加"吃饭"功能,并在页面展示该对象信息。

原始代码实现

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>人类对象示例</title>
<script>
var person={'bianhao':007,'name':'诗书画唱','age':20,'sex':'男','chifan' :function(){alert(this.name+"正在吃饭");}
};for(var i in person){document.write(person[i]+"&nbsp;&nbsp;");
}
document.write("<hr>");
document.write(person.bianhao+"&nbsp;&nbsp;"+person.name + "&nbsp;&nbsp;"+person.age+" &nbsp; &nbsp;"+person.sex);
person.chifan();
</script>
</head>
<body>
</body>
</html>

原始代码解析

  1. 使用对象字面量创建了person对象,包含属性和方法
  2. 通过for...in循环遍历对象属性并输出
  3. 直接通过点语法访问属性并输出
  4. 调用chifan方法弹出提示框

存在的问题

  1. 使用var声明变量,缺乏块级作用域
  2. 编号007作为数字会被解析为7,丢失前导零
  3. 使用document.write()输出内容,不利于页面布局控制
  4. 弹窗提示用户体验不佳
  5. 代码结构混乱,展示逻辑与数据混合

优化方案

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>优化后的人类对象示例</title><style>.person-card {border: 1px solid #ccc;padding: 15px;max-width: 300px;margin: 20px;border-radius: 5px;box-shadow: 0 2px 3px rgba(0,0,0,0.1);}.person-info {margin: 8px 0;}.action-btn {margin-top: 10px;padding: 6px 12px;background-color: #4CAF50;color: white;border: none;border-radius: 4px;cursor: pointer;}.action-btn:hover {background-color: #45a049;}.status {margin-top: 10px;color: #666;font-style: italic;}</style>
</head>
<body><div class="person-card" id="personCard"></div><script>// 使用const声明常量对象,属性使用更规范的命名const person = {id: '007',          // 改为字符串保留前导零name: '诗书画唱',age: 20,gender: '男',       // 使用更规范的属性名// 吃饭方法,改为更新页面状态而非弹窗eat: function() {const statusElement = document.getElementById('status');statusElement.textContent = `${this.name}正在吃饭`;}};// 渲染人员信息到页面function renderPersonInfo(person) {const card = document.getElementById('personCard');// 创建信息展示区域card.innerHTML = `<h3>人员信息</h3><div class="person-info"><strong>编号:</strong>${person.id}</div><div class="person-info"><strong>姓名:</strong>${person.name}</div><div class="person-info"><strong>年龄:</strong>${person.age}</div><div class="person-info"><strong>性别:</strong>${person.gender}</div><button class="action-btn" onclick="person.eat()">执行吃饭动作</button><div class="status" id="status"></div>`;}// 页面加载完成后渲染信息window.onload = function() {renderPersonInfo(person);};</script>
</body>
</html>

优化点说明

  1. 变量声明:使用const替代var,明确变量不可变
  2. 属性命名:使用更规范的英文命名(如id替代bianhaogender替代sex
  3. 数据类型:编号改为字符串类型,保留前导零
  4. 输出方式:使用DOM操作替代document.write(),通过模板字符串构建页面结构
  5. 用户体验:将弹窗提示改为页面内状态更新,添加交互按钮
  6. 代码组织:将渲染逻辑封装为函数,提高可维护性
  7. 样式美化:添加CSS样式,使展示更美观

案例2:人类对象数组创建与遍历

需求说明

创建包含3名人员信息的对象数组,并遍历展示所有人员信息。

原始代码实现

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>人员对象数组</title>
<script>
var persons=[{'bianhao':007,'name':'诗书画唱1','age':20},{'bianhao':666,'name':'诗书画唱2','age':21},{'bianhao':233,'name':'诗书画唱3','age':22},
];for(var i of persons){for(var j in i){document.write(i[j]+"&nbsp;");}document.write("<br>");
}
</script>
</head>
<body>
</body>
</html>

原始代码解析

  1. 创建了包含3个人员对象的数组
  2. 使用for...of遍历数组中的每个对象
  3. 使用for...in遍历每个对象的属性
  4. 通过document.write()输出属性值,使用&nbsp;分隔

存在的问题

  1. 缺乏表头信息,用户无法直观理解各数值含义
  2. 输出格式简陋,数据排列不整齐
  3. 同样存在编号前导零丢失问题
  4. 直接使用document.write()不利于样式控制

优化方案

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>优化后的人员对象数组</title><style>.persons-table {border-collapse: collapse;width: 80%;max-width: 600px;margin: 20px;border: 1px solid #ddd;}.persons-table th, .persons-table td {padding: 12px;text-align: left;border-bottom: 1px solid #ddd;}.persons-table th {background-color: #f2f2f2;font-weight: bold;}.persons-table tr:hover {background-color: #f5f5f5;}</style>
</head>
<body><table class="persons-table" id="personsTable"><!-- 表格内容将通过JS动态生成 --></table><script>// 人员数据数组,使用规范命名和字符串编号const persons = [{ id: '007', name: '诗书画唱1', age: 20 },{ id: '666', name: '诗书画唱2', age: 21 },{ id: '233', name: '诗书画唱3', age: 22 }];// 渲染人员表格function renderPersonsTable(persons) {const table = document.getElementById('personsTable');// 创建表头const thead = document.createElement('thead');thead.innerHTML = `<tr><th>编号</th><th>姓名</th><th>年龄</th></tr>`;table.appendChild(thead);// 创建表体并添加数据行const tbody = document.createElement('tbody');// 使用forEach方法遍历数组,更现代的写法persons.forEach(person => {const row = document.createElement('tr');row.innerHTML = `<td>${person.id}</td><td>${person.name}</td><td>${person.age}</td>`;tbody.appendChild(row);});table.appendChild(tbody);}// 页面加载完成后渲染表格window.onload = function() {renderPersonsTable(persons);};</script>
</body>
</html>

优化点说明

  1. 数据结构:统一使用规范的属性命名,编号改为字符串
  2. 遍历方式:使用forEach方法遍历数组,代码更简洁清晰
  3. 展示方式:使用表格展示数据,添加表头,提高可读性
  4. 样式美化:添加CSS样式,包括hover效果,提升用户体验
  5. 代码组织:将渲染逻辑封装为函数,便于维护和复用
  6. DOM操作:通过创建DOM元素构建表格,而非直接写入文档

案例3:商品构造函数与总价计算

需求说明

创建商品构造函数,实例化3件商品并放入数组,计算并展示商品总价格。

原始代码实现

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>商品总价计算</title>
<script>
var shangPin = function(bianhao, name, price, num) {this.bianhao = bianhao;this.name = name;this.price = price;this.num = num;
}var shangPinShuZu = [new shangPin(1,'苹果', 2, 5),new shangPin(2,'香蕉', 5, 2),new shangPin(3, 'CD', 10, 1)
];alert("计算总价格为:"+jiSuanZongJiaGe(shangPinShuZu));function jiSuanZongJiaGe(shangPinShuZu) {var zongJiaGe = 0; for(var i of shangPinShuZu) {var meiGeShangPinJiaGe = (i.price * i.num);zongJiaGe += meiGeShangPinJiaGe;}return zongJiaGe;
}
</script>
</head>
<body>
</body>
</html>

原始代码解析

  1. 使用构造函数创建shangPin对象类型
  2. 实例化3个商品对象并存储在数组中
  3. 定义jiSuanZongJiaGe函数计算总价
  4. 通过弹窗展示计算结果

存在的问题

  1. 构造函数命名不规范(应使用 PascalCase 命名法)
  2. 仅通过弹窗展示结果,用户体验不佳
  3. 未展示商品列表信息,用户无法核对
  4. 变量命名使用拼音,不符合规范
  5. 缺乏必要的格式处理(如价格保留两位小数)

优化方案

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>商品总价计算</title><style>.product-container {margin: 20px;max-width: 800px;}.product-table {border-collapse: collapse;width: 100%;margin-bottom: 20px;}.product-table th, .product-table td {border: 1px solid #ddd;padding: 12px;text-align: left;}.product-table th {background-color: #f2f2f2;}.total-price {font-size: 18px;font-weight: bold;color: #e74c3c;padding: 10px;border: 1px solid #eee;display: inline-block;}</style>
</head>
<body><div class="product-container"><h2>商品列表</h2><table class="product-table" id="productTable"></table><div id="totalPriceContainer"></div></div><script>// 使用ES6 class语法,更清晰的构造函数class Product {constructor(id, name, price, quantity) {this.id = id;this.name = name;this.price = price;this.quantity = quantity;}// 计算单个商品总价的方法getTotalPrice() {return this.price * this.quantity;}}// 创建商品数组const products = [new Product(1, '苹果', 2, 5),new Product(2, '香蕉', 5, 2),new Product(3, 'CD', 10, 1)];// 计算所有商品的总价function calculateTotalPrice(products) {// 使用reduce方法计算总价,更函数式的写法return products.reduce((total, product) => {return total + product.getTotalPrice();}, 0);}// 渲染商品列表和总价function renderProducts() {const table = document.getElementById('productTable');const totalContainer = document.getElementById('totalPriceContainer');// 创建表头table.innerHTML = `<tr><th>编号</th><th>商品名称</th><th>单价(元)</th><th>数量</th><th>小计(元)</th></tr>`;// 添加商品行products.forEach(product => {const row = document.createElement('tr');const subtotal = product.getTotalPrice();row.innerHTML = `<td>${product.id}</td><td>${product.name}</td><td>${product.price.toFixed(2)}</td><td>${product.quantity}</td><td>${subtotal.toFixed(2)}</td>`;table.appendChild(row);});// 展示总价const totalPrice = calculateTotalPrice(products);totalContainer.innerHTML = `<div class="total-price">商品总价:${totalPrice.toFixed(2)}元</div>`;}// 页面加载完成后渲染window.onload = function() {renderProducts();};</script>
</body>
</html>

优化点说明

  1. 构造函数:使用ES6的class语法,更清晰的面向对象结构
  2. 命名规范:使用英文命名且遵循规范(PascalCase 用于类,camelCase 用于方法和属性)
  3. 方法封装:在类中添加getTotalPrice方法计算单个商品总价
  4. 计算方式:使用reduce方法计算总价,更符合函数式编程风格
  5. 展示方式:通过表格展示完整商品信息,包括单价、数量和小计
  6. 格式处理:使用toFixed(2)确保价格保留两位小数
  7. 用户体验:在页面中展示结果而非弹窗,提供完整的视觉信息

扩展题:对象操作进阶技巧

扩展1:对象控制台输出与方法优化

原始代码实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>对象控制台输出</title>
<script>
// 第一种创建对象方法:直接创建
var duiXiang1={'bianhao':1,'name':'诗书画唱' , 'age':19,'sex':'男'};// 第二种创建对象方法:使用new创建
var duiXiang2=new Object();
duiXiang2.bianhao=2;
duiXiang2.name='诗书画唱SSHC';
duiXiang2.age=19;
duiXiang2.sex='男';duiXiang2.gongneng=function(){alert(this.name+"的功能是吃饭");document.write(this.name+"的功能是吃饭");
}console.log(duiXiang1);
console.log(duiXiang2);window.onload=function() {duiXiang2.gongneng();
}
</script>
</head>
<body>
</body>
</html>
优化方案
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>对象控制台输出优化</title><style>.info-box {margin: 20px;padding: 15px;border: 1px solid #ccc;border-radius: 5px;}.hint {color: #666;font-style: italic;}</style>
</head>
<body><div class="info-box"><h3>对象调试演示</h3><p>请打开浏览器控制台(F12)查看对象信息</p><p class="hint">提示:在控制台中可以展开对象,查看其属性和方法</p><div id="actionResult"></div></div><script>// 使用对象字面量创建(推荐方式)const person1 = {id: 1,name: '诗书画唱',age: 19,gender: '男',// 重写toString方法,便于日志输出toString() {return `${this.name} (${this.id}): ${this.age}岁, ${this.gender}`;}};// 使用Object.create创建对象(适合需要原型继承的场景)const person2 = Object.create(null, {id: { value: 2, writable: true },name: { value: '诗书画唱SSHC', writable: true },age: { value: 19, writable: true },gender: { value: '男', writable: true },// 吃饭方法eat: { value: function() {const resultElement = document.getElementById('actionResult');resultElement.textContent = `${this.name}正在吃饭`;// 在控制台输出详细信息console.log(`${new Date().toLocaleTimeString()}: ${this.name}执行了吃饭动作`);}}});// 控制台输出优化console.group('人员对象信息');console.log('person1 对象:', person1);console.log('person1 字符串表示:', person1.toString());console.log('person2 对象:', person2);console.dir(person2); // 更详细的对象结构展示console.groupEnd();// 页面加载后执行方法window.onload = function() {// 添加按钮触发动作,而非自动执行const button = document.createElement('button');button.textContent = '执行吃饭动作';button.onclick = () => person2.eat();document.body.appendChild(button);};</script>
</body>
</html>

扩展1.1:对象属性的添加与删除

实现代码
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>对象属性操作</title><style>.container {margin: 20px;}.object-display {padding: 15px;background-color: #f8f9fa;border-radius: 5px;margin: 10px 0;white-space: pre-wrap;}button {margin: 5px;padding: 6px 12px;cursor: pointer;}</style>
</head>
<body><div class="container"><h3>对象属性添加与删除演示</h3><div><button onclick="addProperty()">添加属性</button><button onclick="deleteProperty()">删除属性</button><button onclick="modifyProperty()">修改属性</button><button onclick="checkProperty()">检查属性是否存在</button></div><h4>当前对象:</h4><div class="object-display" id="objectDisplay"></div><div id="message"></div></div><script>// 初始对象let person = {id: 1,name: '诗书画唱',age: 19,gender: '男'};// 显示对象当前状态function displayObject() {const displayElement = document.getElementById('objectDisplay');// 格式化输出,便于阅读displayElement.textContent = JSON.stringify(person, null, 2);}// 添加属性function addProperty() {// 检查属性是否已存在if (!person.address) {person.address = '北京市';showMessage('已添加address属性');} else if (!person.hobby) {person.hobby = '阅读';showMessage('已添加hobby属性');} else {showMessage('所有可选属性已添加');}displayObject();}// 删除属性function deleteProperty() {// 删除属性的两种方式if (person.age) {delete person.age;showMessage('已删除age属性');} else if (person.gender) {delete person['gender'];showMessage('已删除gender属性');} else {showMessage('没有可删除的属性');}displayObject();}// 修改属性function modifyProperty() {person.age = person.age ? person.age + 1 : 20;showMessage(`已更新age属性为: ${person.age}`);displayObject();}// 检查属性是否存在function checkProperty() {const hasId = 'id' in person;const hasAddress = 'address' in person;showMessage(`id属性存在: ${hasId}, address属性存在: ${hasAddress}`);}// 显示操作消息function showMessage(text) {const messageElement = document.getElementById('message');messageElement.textContent = text;}// 初始化显示window.onload = function() {displayObject();};</script>
</body>
</html>

扩展1.2:JavaScript数组遍历方法详解

实现代码
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>数组遍历方法详解</title><style>.container {margin: 20px;max-width: 800px;}.method-section {margin-bottom: 30px;padding: 15px;border: 1px solid #eee;border-radius: 5px;}.result {background-color: #f8f9fa;padding: 10px;margin-top: 10px;border-radius: 4px;white-space: pre-wrap;}button {padding: 6px 12px;cursor: pointer;}</style>
</head>
<body><div class="container"><h2>JavaScript数组遍历方法对比</h2><div class="method-section"><h3>1. for循环遍历</h3><button onclick="traverseWithFor()">执行for循环遍历</button><div class="result" id="forResult"></div></div><div class="method-section"><h3>2. for...of遍历</h3><button onclick="traverseWithForOf()">执行for...of遍历</button><div class="result" id="forOfResult"></div></div><div class="method-section"><h3>3. forEach遍历</h3><button onclick="traverseWithForEach()">执行forEach遍历</button><div class="result" id="forEachResult"></div></div><div class="method-section"><h3>4. map遍历(返回新数组)</h3><button onclick="traverseWithMap()">执行map遍历</button><div class="result" id="mapResult"></div></div><div class="method-section"><h3>5. filter遍历(筛选元素)</h3><button onclick="traverseWithFilter()">执行filter遍历</button><div class="result" id="filterResult"></div></div></div><script>// 人员数据数组const persons = [{ id: 1, name: '诗书画唱1', age: 19 },{ id: 2, name: '诗书画唱2', age: 22 },{ id: 3, name: '诗书画唱3', age: 25 }];// 1. for循环遍历function traverseWithFor() {const result = [];for (let i = 0; i < persons.length; i++) {result.push(`[${i}] ${persons[i].name}, ${persons[i].age}`);}document.getElementById('forResult').textContent = result.join('\n');}// 2. for...of遍历function traverseWithForOf() {const result = [];for (const person of persons) {result.push(`${person.name}, ${person.age}`);}document.getElementById('forOfResult').textContent = result.join('\n');}// 3. forEach遍历function traverseWithForEach() {const result = [];persons.forEach((person, index) => {result.push(`[${index}] ${person.name}, ${person.age}`);});document.getElementById('forEachResult').textContent = result.join('\n');}// 4. map遍历(返回新数组)function traverseWithMap() {// map返回一个新数组,包含转换后的值const mapped = persons.map(person => {return {fullInfo: `${person.name} (ID: ${person.id})`,ageGroup: person.age < 20 ? '青年' : '成年'};});document.getElementById('mapResult').textContent = JSON.stringify(mapped, null, 2);}// 5. filter遍历(筛选元素)function traverseWithFilter() {// filter返回符合条件的元素组成的新数组const adults = persons.filter(person => person.age >= 20);document.getElementById('filterResult').textContent = JSON.stringify(adults, null, 2);}</script>
</body>
</html>

总结与进阶建议

通过对以上案例的解析与优化,我们可以总结出JavaScript对象与数组操作的最佳实践:

  1. 命名规范:使用有意义的英文名称,遵循PascalCase(类)和camelCase(方法、属性)命名法
  2. 变量声明:优先使用constlet,避免使用var,明确变量的可变性
  3. 对象创建
    • 简单对象推荐使用对象字面量{}
    • 复杂对象或需要多次实例化时使用class
    • 避免使用new Object()创建对象
  4. 数组遍历
    • 简单遍历推荐使用forEach
    • 需要返回新数组时使用map
    • 需要筛选元素时使用filter
    • 需要计算累加结果时使用reduce
  5. DOM操作:避免使用document.write(),通过createElementtextContent等方法操作DOM
  6. 代码组织:将功能封装为函数,提高复用性和可维护性

进阶学习建议

  1. 学习ES6+更多特性:箭头函数、解构赋值、展开运算符等
  2. 掌握数组高级方法:find(), some(), every(), sort()
  3. 学习对象的原型与继承机制
  4. 了解Immutable数据处理理念,避免直接修改对象
  5. 学习TypeScript,为对象和数组添加类型定义,提高代码健壮性

通过不断实践这些技巧,你将能够写出更规范、高效、可维护的JavaScript代码,为构建复杂前端应用打下坚实基础。

http://www.xdnf.cn/news/18993.html

相关文章:

  • linux安装海康工业相机MVS SDK(3.0)会导致ROS的jsk插件崩溃
  • Java IO 流-详解
  • 从零开始学习单片机16
  • 循环高级(2)
  • 血缘元数据采集开放标准:OpenLineage Integrations Manually Annotated Lineage
  • 企业级数据库管理实战(二):数据库权限最小化原则的落地方法
  • 【分治法 BFS 质因数分解】P12255 [蓝桥杯 2024 国 Java B] 园丁|普及+
  • 智慧养老建设方案(PPT)
  • 开源大语言模型(Qwen3)
  • 深入探讨可视化技术如何实现安全监测
  • 【小白笔记】Visual Studio 在 2025年7月更新的功能说明(英文单词记忆)
  • 智慧工地系统:基于Java微服务与信创国产化的建筑施工数字化管理平台
  • 171-178CSS3新增
  • NullPointerException 空指针异常,为什么老是遇到?
  • 评价指标FID/R Precision
  • vscode编辑器中设置断点,不会自动启动调试器
  • 介绍⼀下Llama的结构
  • Spring Boot 整合 MongoDB:CRUD 与聚合查询实战
  • Jenkins 全方位指南:安装、配置、部署与实战应用(含图解)
  • 如何规划一年、三年、五年的IP发展路线图?
  • 01.<<基础入门:了解网络的基本概念>>
  • Leetcode 深度优先搜索 (15)
  • WINTRUST!_ExplodeMessag函数中的pCatAdd
  • Yolov8 pose 推理部署笔记
  • Vue开发避坑:箭头函数与普通函数的正确使用指南
  • LeetCode 刷题【55. 跳跃游戏】
  • 从协作机器人到智能协作机器人:工业革命的下一跳
  • 【JavaScript】递归的问题以及优化方法
  • 安宝特方案丨安宝特工业AR全链路解决方案
  • Unity游戏打包——iOS打包基础、上传