【JavaScript学习|黑马2023课程】js基础day05——对象的使用、操作,数据类型
文章目录
1.1对象是什么
对象 (Object): JavaScript中的一种数据类型。可以理解为一种无序的数据集合,不同于数组的有序数据集合。
对象用于描述某个事物,例如描述一个人:
- 人有姓名、年龄、性别等信息,还有吃饭、睡觉、打代码等功能。
- 如果用多个变量保存,则比较散,而使用对象可以更统一。
对象包括两个核心部分:
- 静态特征: 包括姓名、年龄、身高、性别等,可以使用数字、字符串、数组、布尔类型等表示。
- 动态行为: 包括点名、唱歌、跳舞、rap等。
1.2对象使用
1.2.1 对象声明语法
对象可以通过字面量方式声明,也可以通过构造函数方式声明:
// 字面量方式
let 对象名 = {};
// 构造函数方式
let 对象名 = new Object();
通常我们更倾向于使用对象字面量,即花括号 {}
。
1.2.2 对象的属性和方法
一个对象由属性和方法组成:
- 属性(Properties): 描述性的信息,如姓名、身高、年龄,通常是名词性的。
- 方法(Methods): 对象的行为和功能,通常是动词性的。
let 对象名 = {
属性名: 属性值,
方法名: 函数
};
1.2.3 属性
属性是对象的数据描述信息,包括属性名和属性值。多个属性之间使用英文逗号 ,
分隔。属性名和值之间使用英文冒号 :
分隔。
属性可以是字符串,也可以是没有引号的标识符。通常情况下省略引号,除非属性名包含特殊符号如空格、中横线等。
示例:
let 人 = {
姓名: "张三",
年龄: 25,
性别: "男",
身高: 175,
吃饭: function() {
console.log("吃饭");
}
};
上述对象描述了一个人的静态特征和动态行为。姓名、年龄、性别、身高是属性,而吃饭是一个方法。
1.2.4 操作对象
对象是JavaScript中非常重要的数据类型,它允许我们存储多个值作为属性,并且可以包含方法。操作对象主要包括增添新值、删除属性、修改属性和查找属性。
①增添新值
我们可以通过简单的赋值语法为对象添加新的属性。例如:
let person = {}; // 声明一个空对象
person.name = "Alice"; // 添加name属性并赋值为"Alice"
②删除属性
使用delete
关键字可以从对象中删除属性。例如:
delete person.name; // 删除对象的name属性
③修改属性
修改对象的属性值也是通过赋值语法完成的。例如:
person.name = "Bob"; // 将name属性的值修改为"Bob"
④查找属性
我们可以使用点记法或者方括号记法来访问对象的属性。例如:
console.log(person.name); // 输出name属性的值
console.log(person["name"]); // 输出name属性的值,使用方括号记法
注意,如果属性名包含特殊字符或者与JavaScript关键字重名,必须使用方括号记法,并且属性名要用引号包围。例如:
let obj = { "first-name": "Alice" };
console.log(obj["first-name"]); // 输出"Alice"
1.2.5 对象的方法
对象是属性的集合,这些属性可以是数据或者函数。当属性是函数时,我们称之为对象的方法。方法是对象的行为,用于执行某些操作。例如:
let person = {
name: "Alice",
sayHello: function() {
console.log("Hello, my name is " + this.name);
}
};
在上面的例子中,sayHello
是person
对象的一个方法。注意方法内部的this
关键字,它指代当前对象。在sayHello
方法中,this.name
就是person.name
。
1.2.6 调用对象中的方法
调用对象中的方法与调用普通函数类似,只是需要通过对象来调用。例如:
person.sayHello(); // 输出"Hello, my name is Alice"
1.3 遍历对象
遍历对象主要用于访问对象的所有属性,通常使用 for...in
循环来实现。在 for...in
循环中,我们可以获取到对象的属性名,进而获取到属性值。
let person = {
name: "Andy",
age: 18,
gender: "男",
};
for (let k in person) {
console.log(k);
//console.log(person.k); person对象没有一个名为"k"的属性,所以person.k将返回undefined
console.log(person[k]);
}
示例中的代码展示了如何使用 for...in
循环遍历一个对象,并通过 console.log()
输出每个属性的名称和值。需要注意的是,由于属性名是通过变量 k
来表示的,因此必须使用方括号语法 person[k]
来访问属性值。
案例:遍历数组对象并渲染生成表格
给定一个包含多个学生信息的数组对象 students
,我们需要遍历这个数组并生成一个表格。这里我们可以使用 for...in
循环嵌套来遍历数组中的每个对象,并获取其属性值。
let students = [
{ name: "小明", age: 18, gender: "男", hometown: "河北省" },
{ name: "小红", age: 19, gender: "女", hometown: "河南省" },
{ name: "小刚", age: 17, gender: "男", hometown: "山西省" },
{ name: "小丽", age: 18, gender: "女", hometown: "山东省" },
];
代码实现:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
table {
width: 600px;
text-align: center;
}
table,
th,
td {
border: 1px solid #ccc;
border-collapse: collapse;
}
caption {
font-size: 18px;
margin-bottom: 10px;
font-weight: 700;
}
tr {
height: 40px;
cursor: pointer;
}
table tr:nth-child(1) {
background-color: #ddd;
}
table tr:not(:first-child):hover {
background-color: #eee;
}
</style>
</head>
<body>
<table>
<caption>
<h3>学生列表</h3>
</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<script>
let students = [
{ name: "小明", age: 18, gender: "男", hometown: "河北省" },
{ name: "小红", age: 19, gender: "女", hometown: "河南省" },
{ name: "小刚", age: 17, gender: "男", hometown: "山西省" },
{ name: "小丽", age: 18, gender: "女", hometown: "山东省" },
];
for (let i = 0; i < students.length; i++) {
document.write(`
<tr>
<td>${i + 1}</td>
<td>${students[i].name}</td>
<td>${students[i].age}</td>
<td>${students[i].gender}</td>
<td>${students[i].hometown}</td>
</tr>
`);
}
</script>
</table>
</body>
</html>
1.4 内置对象
在JavaScript中,内置对象是由语言本身提供的,开发者可以直接使用而无需定义。这些内置对象提供了许多实用的方法和属性,帮助开发者完成各种任务。例如,前面提到的document
和console
都是内置对象,分别用于操作网页文档和输出日志。
1.5 内置对象——Math
Math
对象是JavaScript中的一个内置对象,专门用于数学运算。它提供了许多与数学相关的属性和方法。下面是一些常用的Math
对象方法:
1.5.1 常见方法
random()
random()
方法用于生成一个介于0(包含)和1(不包含)之间的随机浮点数。例如:
let randomNum = Math.random(); // 生成一个0-1之间的随机数
console.log(randomNum);
ceil()
ceil()
方法用于向上取整,即返回大于或等于一个给定数字的最小整数。例如:
let num = 3.14;
let roundedUp = Math.ceil(num); // 向上取整为4
console.log(roundedUp);
floor()
floor()
方法用于向下取整,即返回小于或等于一个给定数字的最大整数。例如:
let num = 3.14;
let roundedDown = Math.floor(num); // 向下取整为3
console.log(roundedDown);
max() 和 min()
max()
方法返回一组数中的最大值,而min()
方法返回一组数中的最小值。例如:
let maxValue = Math.max(1, 2, 3, 4, 5); // 返回5
let minValue = Math.min(1, 2, 3, 4, 5); // 返回1
console.log(maxValue, minValue);
pow()
pow()
方法进行幂运算,即返回第一个参数的第二个参数次方。例如:
let result = Math.pow(2, 3); // 返回8(2的3次方)
console.log(result);
abs()
abs()
方法返回一个数字的绝对值。例如:
let num = -10;
let absoluteValue = Math.abs(num); // 返回10的绝对值10
console.log(absoluteValue);
1.5.2 生成任意范围随机数
Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数 [0, 1)
let num1 = Math.floor(Math.random() * (10 + 1));
let num2 = Math.floor(Math.random() * (5 + 1)) + 5;
function getRandom(N, M) {
//生成N-M之间的随机数
return Math.floor(Math.random() * (M - N + 1)) + N;
}
let num3 = getRandom(2, 8);
console.log(num1);
console.log(num2);
console.log(num3);
案例1:随机点名
需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中
let nameList = ["赵云", "黄忠", "关羽", "张飞", "马超", "刘备", "曹操"];
// 计算名字数组的长度,并将结果减去1存储在变量 len 中
let len = nameList.length - 1;
// 生成一个随机数,范围在0到数组最大索引之间(包括最大索引)
let randomNum = Math.floor(Math.random() * (len + 1));
// 将随机生成的索引值加1并写入到文档中(因为数组的索引是从0开始的)
document.write("随机索引值: " + (randomNum + 1));
// 将被随机选择的名字写入到文档中,该名字是通过使用随机生成的索引值从名字数组中获取的
document.write(" 随机选择的三国人物名称: " + nameList[randomNum]);
案例2:生成随机颜色
需求:该函数接收一个布尔类型参数,表示颜色的格式是十六进制还是rgb格式。
①:如果参数传递的是true或者无参数,则输出 一个随机十六进制的颜色
②:如果参数传递的是false,则输出 一个随机rgb的颜色
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box1 {
margin: 20px auto;
width: 100px;
height: 100px;
border: 1px solid #000; /* 为了看清边界,添加边框样式 */
}
.box2 {
margin: 20px auto;
width: 100px;
height: 100px;
border: 1px solid #000; /* 为了看清边界,添加边框样式 */
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
<script>
function getRandom(flag = true) {
// 如果是true 返回#ffffff ;否则返回rgb(255,255,255)。添加默认值
if (flag) {
let str = "#";
let arr = [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
"a",
"b",
"c",
"d",
"e",
"f",
];
for (let i = 0; i < 6; i++) {
let num = Math.floor(Math.random() * arr.length);
str += arr[num];
}
return str;
} else {
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
return `rgb(${r},${g},${b})`;
}
}
// 获取随机颜色并应用到box1
let box1 = document.querySelector(".box1");
box1.style.backgroundColor = getRandom(false);
// 获取随机颜色并应用到box2
let box2 = document.querySelector(".box2");
box2.style.backgroundColor = getRandom(true);
</script>
</body>
</html>
案例3:学成在线页面渲染
代码实现,通过循环获取数组中对象值(需要完整css以及图片直接复制粘贴不会出图片,仅展示效果)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>学成在线首页</title>
<link rel="stylesheet" href="./css/style.css" />
<style></style>
</head>
<body>
<!-- 4. box核心内容区域开始 -->
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">
<script>
let data = [
{
src: "images/course01.png",
title: "Think PHP 5.0 博客系统实战项目演练",
num: 1125,
},
{
src: "images/course02.png",
title: "Android 网络动态图片加载实战",
num: 357,
},
{
src: "images/course03.png",
title: "Angular2 大前端商城实战项目演练",
num: 22250,
},
{
src: "images/course04.png",
title: "Android APP 实战项目演练",
num: 389,
},
{
src: "images/course05.png",
title: "UGUI 源码深度分析案例",
num: 124,
},
{
src: "images/course06.png",
title: "Kami2首页界面切换效果实战演练",
num: 432,
},
{
src: "images/course07.png",
title: "UNITY 从入门到精通实战案例",
num: 888,
},
{
src: "images/course08.png",
title: "Cocos 深度学习你不会错过的实战",
num: 590,
},
];
for (let i = 0; i < data.length; i++) {
document.write(`
<li>
<a href="#">
<img src=${data[i].src} alt="">
<h4>
${data[i].title}
</h4>
<div class="info">
<span>高级</span> • <span>${data[i].num}</span>人在学习
</div>
</a>
</li>
`);
}
</script>
<!-- <li>
<a href="#">
<img src="images/course01.png" alt="">
<h4>
Think PHP 5.0 博客系统实战项目演练
</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li><li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li>
<li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li>
<li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li>
<li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li>
<li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li>
<li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li>
<li>
<a href="#">
<img src="images/course01.png" alt="" />
<h4>Think PHP 5.0 博客系统实战项目演练</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li> -->
</ul>
</div>
</div>
</body>
</html>
1.6 基本数据类型和引用数据类型
①认识数据类型
在编程中,数据类型是一个重要的概念。JavaScript中有两种主要的数据类型:基本数据类型和引用数据类型。
-
基本数据类型(值类型):这些类型包括
string
(字符串)、number
(数字)、boolean
(布尔值)、undefined
(未定义)和null
(空)。当我们声明一个变量并为其赋值时,如果值是这些基本类型之一,那么变量中存储的就是这个值本身。 -
引用数据类型:这些类型通常是通过使用
new
关键字创建的对象,如Object
、Array
、Date
等。当我们创建一个对象并将其赋值给变量时,变量中存储的实际上是一个指向该对象在内存中位置的引用或地址,而不是对象本身。
②堆栈空间分配区别
在计算机内存中,数据的存储方式有两种主要的空间:栈和堆。
- 栈:栈是用于存储函数调用和局部变量的数据结构。当我们声明一个基本数据类型的变量时,这个变量的值会被直接存储在栈内存中。栈内存的分配和释放是由操作系统自动管理的。
- 堆:堆是用于存储引用数据类型(如对象)的内存空间。与栈不同,堆内存中的数据分配和释放通常由程序员来管理。如果程序员没有明确释放一个对象所占用的内存,那么这些内存将由JavaScript的垃圾回收机制来自动回收。
了解基本数据类型和引用数据类型的区别以及它们在内存中的存储方式对于编写高效和安全JavaScript代码非常重要。通过理解数据的存储方式,我们可以更好地管理内存使用,避免不必要的内存泄漏,并优化代码的性能。
问题:以下代码会输出什么?(堆栈问题)
let num = 10;
let num2 = num;
num = 20;
console.log(num2);
let obj1 = {
age: 18,
};
let obj2 = obj1;
obj1.age = 20;
console.log(obj2.age);
解释:
可以通过堆栈(Stack)的概念来解释这个过程。在堆栈中,每次函数调用或变量赋值都会创建一个新的帧(frame),帧包含了当前函数的信息或变量的值。当函数执行完成或变量超出作用域时,对应的帧就会从堆栈中移除(出栈)。
基本数据类型:
-
初始化时,堆栈如下:
| | | | | num | <--- num 的值为 10 |___________|
-
执行
let num2 = num;
,创建一个新的帧:| | | num | <--- num 的值为 10 | num2 | <--- num2 的值为 10 |___________|
-
执行
num = 20;
,更新当前帧的num
值:| | | num | <--- num 的值为 20 | num2 | <--- num2 的值为 10 |___________|
-
执行
console.log(num2);
,打印当前帧中num2
的值,输出10
。
然后是引用数据类型:
-
初始化时,堆栈如下:
| | | | | obj1 | <--- obj1 包含属性 age 值为 18 | obj2 | <--- obj2 和 obj1 指向同一个对象 |___________|
-
执行
obj1.age = 20;
,更新对象的属性值:| | | | | obj1 | <--- obj1 包含属性 age 值为 20 | obj2 | <--- obj2 和 obj1 指向同一个对象 |___________|
-
执行
console.log(obj2.age);
,打印当前帧中obj2.age
的值,输出20
。
在基本数据类型的情况下,值是直接存储在变量中的,因此对一个变量的修改不会影响到另一个变量。而在引用数据类型的情况下,变量存储的是对象的引用,因此对对象的修改会影响到所有引用该对象的变量。