主题
1-15对象和对象操作(一)
本页对应 第一章JavaScript基础,共 5 段视频,约 53 分钟。
学习目标
- 能够用对象字面量定义包含属性和方法的对象,并说明属性名与属性值、方法名与匿名函数之间的分隔规则及对象无序性。
- 能够使用点语法访问对象属性、调用对象方法,并给方法传递参数、接收返回值,说明方法本质是函数且调用时必须加小括号。
- 能够对对象完成增删改查操作:新增或修改属性与方法、使用
delete删除指定属性或方法,并解释新增与修改语法相同但语义不同。 - 能够使用
对象["属性名"]读取属性,说明中括号内属性需加引号,并能判断何时使用点语法、何时使用中括号语法。 - 能够使用
for...in遍历对象属性,通过循环变量取得属性名、通过对象[变量]取得属性值,并说明循环变量不能加引号。 - 能够区分
for...in遍历对象与遍历数组的差异,说明数组应使用传统for循环,避免字符串索引带来的问题。
知识点
对象是什么:用键值对把数据说清楚
为什么需要:数组也能存数据,但存“佩奇、女、4、12.6”时,普通用户看不出每个值代表什么;对象用键值对存储,语义更直观。怎么想:对象是 JavaScript 的一种引用数据类型,用来详细描述某个事物;属性一般是名词性信息,方法一般是行为性信息。怎么做:用大括号声明对象,数据无序,属性名和值用英文冒号分隔,多组数据用英文逗号分隔。易错点:对象属性无序,谁前谁后不影响按名访问;最后一个属性后不加逗号;属性在对象外叫变量,在对象内叫属性,属性不需要 let 声明。
html
<script>
// 对象也是一种数据类型,保存数据同时可以更直观的描述事物
// 1. 定义对象属性
let pig = {
sex: '女',
age: 4,
uname: '佩奇',
weight: 12.6
}
</script>定义和访问对象属性
为什么需要:定义属性后要取出值使用。怎么想:属性像对象里的“容器”,点语法可理解为“的”:pig.age 就是“pig 的 age”。怎么做:定义后用 对象.属性 访问。转写稿中的调试过程是:直接 console.log(age) 会报 age is not defined,因为 age 不是变量;写成 pig.age 才能得到 4,pig.weight 得到 12.6。易错点:不要把属性名当独立变量;点语法适合普通单词属性。
html
<script>
// 对象也是一种数据类型,保存数据同时可以更直观的描述事物
// 1. 定义对象属性
let pig = {
sex: '女',
age: 4,
uname: '佩奇',
weight: 12.6
}
// 2. 访问对象属性 对象.属性
console.log(pig.age) // 4
console.log(pig.weight) // 12.6
</script>定义和调用对象方法
为什么需要:对象不仅描述“是什么”,还要描述“能做什么”,如唱歌、跳舞。怎么想:方法本质是函数;对象外叫函数,对象内叫方法。怎么做:方法名后写英文冒号和匿名函数,多个方法用逗号分隔;调用用 对象.方法()。方法也可传参、有返回值。易错点:方法名和匿名函数之间用冒号,不是等号;调用别忘了小括号;同一对象中名称相同,后面的覆盖前面的。
javascript
// let fn = function() {}
// 对象方法
// 1. 定义对象方法
let pig = {
uname: '佩奇',
sing: function () {
console.log('唱歌')
},
dance: function () {
console.log('跳舞')
},
sum: function (x, y) { // 2
// console.log(x + y)
return x + y
}
}
console.log(pig)
// 2. 调用对象方法
pig.sing() // 唱歌
pig.dance() // 跳舞
// 3. 方法可以传递参数也可以有返回值,跟函数使用基本类似
let re = pig.sum(1, 2) // 1 实参
console.log(re)增删改查对象
为什么需要:对象是无序数据集合,实际开发要查、增、改、删。怎么想:查用 对象.属性 或 对象.方法();增用 对象.新属性 = 新值;改用 对象.属性 = 新值;删用 delete 对象.属性。增和改语法一样:原来有就是改,原来没有就是增。怎么做:看下面代码。易错点:删除在开发中较少用,作了解;改方法要赋新的匿名函数;查方法要加小括号才会执行。


javascript
<script>
// 操作对象:对数据 查、增、改、删
let pig = {
uname: '佩奇',
sing: function () {
console.log('唱歌')
}
}
// 1. 查: 对象.属性 对象.方法
console.log(pig.uname) // 得到属性值
pig.sing()
// 2. 增:对象.新属性 = 新值 对象.新方法 = function(){}
pig.age = 4
pig.dance = function () {
console.log('跳舞')
}
console.log(pig)
// 3. 改:对象.属性 = 新值 对象.方法 = 新匿名函数
pig.uname = '小猪佩奇'
pig.sing = function () {
console.log('哼哼哼!!')
}
console.log(pig)
// 4. 删: 了解,因为我们很少对对象里面的数据做删除操作 delete
delete pig.age
delete pig.dance
console.log(pig)
</script>中括号访问属性
为什么需要:多词属性如 pig-name 不能用点语法,因为 pig.pig-name 会被当成减法。怎么想:用 对象['属性'] 访问。转写稿调试显示:console.log(pig.pig - name) 得到 NaN,因为 pig.pig 不存在;pig['pig-name'] 才能得到“佩奇”。怎么做:中括号里写属性字符串;普通属性也可写 pig['age'],等价于 pig.age。易错点:中括号里的属性名要加引号;普通属性仍推荐点语法;解析变量时中括号里放变量,变量不加引号。
javascript
<script>
// 查询属性的另外写法 对象['属性'] 这个属性必须加引号
let pig = {
'pig-name': '佩奇',
age: 4
}
// console.log(pig.pig - name) // NaN
console.log(pig['pig-name']) // 佩奇
console.log(pig['age']) // 4 === pig.age
</script>for in 遍历对象
为什么需要:对象没有 length 且无序,传统 for 不适合批量取对象属性。怎么想:用 for in,变量 key 依次得到属性名,对象[key] 得到属性值。转写稿调试:写 pig.key 会得到 undefined,因为 key 是变量不是属性名;写 pig[key] 才对。怎么做:见代码。易错点:key 是属性名,pig[key] 是值;key 不要加引号,加了就当字符串;数组遍历用传统 for,for in 主要遍历对象,数组会得到字符串索引。
javascript
<script>
// 遍历对象
let pig = {
sex: '女',
age: 4,
uname: '佩奇',
weight: 12.6,
}
// for (let key in pig) {
// console.log(key) // key 是属性
// console.log(pig[key]) // 对象[变量] 是值
// }
for (let key in pig) {
console.log(key) // key 是属性 对象.属性
// console.log(pig.key) // pig.key undefined 因为key是个变量不是属性
// key 'sex' 'age' 对象[key] 对象['sex'] 对象['age']
console.log(pig[key])
}
// 注意:数组遍历用传统for, for in 主要用来遍历对象
let arr = ['red', 'green', 'pink']
for (let k in arr) {
console.log(k)// 得到字符串类型的索引号
}
</script>内置对象是什么
为什么需要:JavaScript 内部已经提供了一些对象,里面封装好属性和方法,开发者直接调用即可,不必自己从头实现。笔记里说“内置对象:JavaScript内部提供的对象,包含各种属性和方法给开发者调用”。比如我们常用的 console.log,console 就是内置对象,log 是它里面的方法。
怎么想:先区分“属性”和“方法”。属性通常写成 对象.属性,方法通常写成 对象.方法()。转写稿里反复强调“对象点属性”“对象点方法”,同音字里的“中国号”应理解为中括号,“便历”应理解为遍历。内置对象也遵循这个访问规则。
怎么做:遇到数学计算,先想到 Math;遇到控制台输出,想到 console。调用前看它是属性还是方法:Math.PI 不加括号,Math.max(8,3,1) 要加括号并传参数。
易错点:不要把属性当方法调用,例如 Math.PI() 是错的;也不要把方法当属性,例如只写 Math.max 不会得到最大值。
Math 对象
为什么需要:做圆周率、最大值、最小值、绝对值、取整等数学运算时,Math 提供了现成能力。笔记表格如下:
| 属性/方法 | 作用 | 说明 |
|---|---|---|
| PI | 圆周率 | Math.PI 属性,返回圆周率 |
| max | 找最大值 | Math.max(8, 3, 1) 方法,返回 8 |
| min | 找最小值 | Math.min(8, 3, 1) 方法,返回 1 |
| abs | 绝对值 | Math.abs(-1) 方法,返回 1 |
| ceil | 向上取整 | Math.ceil(3.1) 方法,返回 4 |
| floor | 向下取整 | Math.floor(3.8) 方法,返回 3 |
| round | 四舍五入取整 | Math.round(3.8) 方法,返回 4, 遇到.5则舍入到相邻的在正无穷(+∞)方向上的整数 |
怎么想:Math 是数学对象,既有属性也有方法。先看名字:PI 是属性;max/min/abs/ceil/floor/round 是方法。方法要传参数,返回值可以直接 console.log 查看。
怎么做:把下面代码放进 <script>,逐条运行,对照注释看控制台输出:
javascript
<script>
// 内置对象Math
// 1. PI 属性 圆周率
console.log(Math.PI)
// 2. max 方法 找最大值
console.log(Math.max(8, 4, 2)) // 8
// 3. min 方法 找最小值
console.log(Math.min(8, 4, 2)) // 2
// 4. abs 方法 取绝对值
console.log(Math.abs(-1)) // 1
// 5. ceil 方法 向上取整 ceil 天花板 往大了取
console.log(Math.ceil(1.1)) // 2
console.log(Math.ceil(1.5)) // 2
console.log(Math.ceil(1.8)) // 2
console.log(Math.ceil(-1.1)) // -1
console.log(Math.ceil(-1.5)) // -1
console.log(Math.ceil(-1.8)) // -1
// 6. floor 方法 向下取整 floor 地板 往小了取
console.log(Math.floor(1.1)) // 1
console.log(Math.floor(1.5)) // 1
console.log(Math.floor(1.8)) // 1
console.log(Math.floor(-1.1)) // -2
console.log(Math.floor(-1.5)) // -2
console.log(Math.floor(-1.8)) // -2
// 7. round 方法 四舍五入取整
console.log(Math.round(1.1)) // 1
console.log(Math.round(1.5)) // 2
console.log(Math.round(1.8)) // 2
console.log(Math.round(-1.1)) // -1
console.log(Math.round(-1.8)) // -2
console.log(Math.round(-1.5)) // -1
</script>易错点:取整要特别注意负数。Math.ceil(-1.1) 是向大了取,得到 -1;Math.floor(-1.1) 是向小了取,得到 -2。Math.round(-1.5) 按笔记说明“遇到.5则舍入到相邻的在正无穷方向上的整数”,结果是 -1,不是 -2。数学对象方法不要求强记,通过演示理解对象的使用即可。
随机数 random
为什么需要:做抽奖、随机点名、随机数游戏时,需要生成随机数。Math.random() 返回一个 0 - 1 之间、包括0不包括1的随机小数,即 [0, 1)。
怎么想:Math.random() 本身是小数,要整数就配合 Math.floor()。先生成 0~10:Math.random() 乘 11 得 [0,11),再向下取整就是 0~10。
怎么做:
javascript
Math.floor(Math.random() * (10 + 1))生成 5~15 的随机整数:先得到 0~10,再加最小值 5:
javascript
Math.floor(Math.random() * (10 + 1)) + 5生成 N-M 之间的随机整数:
javascript
Math.floor(Math.random() * (M - N + 1)) + N
Math.floor(Math.random() * (差值 + 1)) + 最小值易错点:Math.random() 取不到1;公式里是“差值 + 1”,最后加“最小值”。完整演示如下:
javascript
<script>
// 1. Math随机数 Math.random()
// 1.1 随机的小数 0 ~1 之间
// 1.2 能取到0,但是取不到1 [0, 1)
// console.log(Math.random())
// 2. 取 0 ~ 10 之间的一个随机整数
// Math.random() * (10 + 1)
// (0 ~ 0.99999) * 11
// 0 ~ 10.99999
// Math.floor(Math.random() * (10 + 1))
// console.log(Math.floor(Math.random() * (10 + 1)))
// 3. 取 5 ~ 15 之间的一个随机整数
// Math.floor(Math.random() * (10 + 1)) 0 ~ 10
// Math.floor(Math.random() * (10 + 1)) + 5 5 ~ 15
// console.log(Math.floor(Math.random() * (10 + 1)) + 5)
// 4. 取 n ~ m 之间的一个随机整数 4 ~ 12
// Math.floor(Math.random() * (差值 + 1)) + 最小值
console.log(Math.floor(Math.random() * (8 + 1)) + 4)
</script>调试时逐条取消注释、运行、看控制台结果;不要只背公式,要理解“先放大区间、再向下取整、最后平移最小值”的推导过程。
课件图示








代码示例
示例一:对象的属性、方法与增删改查
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>对象基本使用</title>
</head>
<body>
<script>
// 1. 定义对象属性
let pig = {
sex: '女',
age: 4,
uname: '佩奇',
weight: 12.6
}
// 2. 访问对象属性 对象.属性
console.log(pig.age) // 4
console.log(pig.weight) // 12.6
// 3. 定义对象方法
let peppa = {
uname: '佩奇',
sing: function () {
console.log('唱歌')
},
dance: function () {
console.log('跳舞')
},
sum: function (x, y) {
return x + y
}
}
console.log(peppa)
// 4. 调用对象方法
peppa.sing() // 唱歌
peppa.dance() // 跳舞
let re = peppa.sum(1, 2) // 方法可以传参也可以有返回值
console.log(re) // 3
// 5. 操作对象:查 增 改 删
let obj = {
uname: '佩奇',
sing: function () {
console.log('唱歌')
}
}
// 查:对象.属性 对象.方法
console.log(obj.uname)
obj.sing()
// 增:对象.新属性 = 新值 对象.新方法 = function(){}
obj.age = 4
obj.dance = function () {
console.log('跳舞')
}
console.log(obj)
// 改:对象.属性 = 新值 对象.方法 = 新匿名函数
obj.uname = '小猪佩奇'
obj.sing = function () {
console.log('哼哼哼!!')
}
console.log(obj)
// 删:了解即可,开发中很少删除对象数据
delete obj.age
delete obj.dance
console.log(obj)
// 6. 查找属性的另外写法:对象['属性'],中括号里的属性必须加引号
let p2 = {
'pig-name': '佩奇',
age: 4
}
console.log(p2['pig-name']) // 佩奇
console.log(p2['age']) // 4 === p2.age
</script>
</body>
</html>关键行与易错点
- 属性名与属性值之间用英文
:分隔,多个属性之间用英文,分隔,最后一组后面不加逗号。 - 属性在对象外叫变量,在对象内叫属性,不需要 let 声明;方法同理,对象外是函数,对象内是方法。
- 方法定义处写的是冒号,不是等号:
sing: function () {}。 - 调用方法必须带小括号:
peppa.sing(),否则拿到的是函数本身而不是执行结果。 - 同一对象中出现同名属性/方法,后面的覆盖前面的。
- 新增和修改语法一样,都是
对象.属性 = 新值:对象里原来有就是改,没有就是增。 pig.pig-name会被解析成减法,结果为 NaN,多词属性(中横线等)必须用对象['pig-name'],且中括号内属性必须加引号。console.log(pig.age)不能写成console.log(age),会报age is not defined。
示例二:for in 遍历对象
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>遍历对象</title>
</head>
<body>
<script>
// 遍历对象
let pig = {
sex: '女',
age: 4,
uname: '佩奇',
weight: 12.6
}
for (let key in pig) {
console.log(key) // key 是属性名
// console.log(pig.key) // pig.key undefined,因为 key 是变量不是属性
console.log(pig[key]) // 对象[变量] 是属性值
}
// 注意:数组遍历用传统 for,for in 主要用来遍历对象
let arr = ['red', 'green', 'pink']
for (let k in arr) {
console.log(k) // 得到字符串类型的索引号
}
</script>
</body>
</html>关键行与易错点
- 对象没有
length而且是无序的,所以不能用传统 for 循环遍历对象,要用for (let 变量 in 对象)。 for in中的k是变量,循环中依次代表属性名,所以必须用对象[k]解析,不能用对象.k(会得到 undefined)。对象[k]中的k绝对不能加引号,加了引号就变成字符串,拿不到属性值(结果为 undefined)。- 属性名用
key(键)命名更符合语义,k、key都是常见写法。 for in遍历数组得到的是字符串类型的索引号,容易出问题,数组还是用传统 for。
示例三:内置对象 Math 与随机数
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Math 内置对象</title>
</head>
<body>
<script>
// 1. PI 属性 圆周率
console.log(Math.PI)
// 2. max / min 找最大 / 最小值
console.log(Math.max(8, 4, 2)) // 8
console.log(Math.min(8, 4, 2)) // 2
// 3. abs 取绝对值
console.log(Math.abs(-1)) // 1
// 4. ceil 向上取整(天花板,往大了取)
console.log(Math.ceil(1.1)) // 2
console.log(Math.ceil(-1.5)) // -1
// 5. floor 向下取整(地板,往小了取)
console.log(Math.floor(1.8)) // 1
console.log(Math.floor(-1.5)) // -2
// 6. round 四舍五入取整
console.log(Math.round(1.5)) // 2
console.log(Math.round(-1.5)) // -1
// 7. random 随机数,返回 [0, 1) 之间的小数,能取到 0 取不到 1
console.log(Math.random())
// 取 0 ~ 10 之间的一个随机整数
console.log(Math.floor(Math.random() * (10 + 1)))
// 取 5 ~ 15 之间的一个随机整数
console.log(Math.floor(Math.random() * (10 + 1)) + 5)
// 取 n ~ m 之间的一个随机整数:Math.floor(Math.random() * (M - N + 1)) + N
// 例:4 ~ 12
console.log(Math.floor(Math.random() * (8 + 1)) + 4)
</script>
</body>
</html>关键行与易错点
Math是内置对象,本身包含属性(PI)和方法(max、min、abs、ceil、floor、round、random),调用时不要漏掉Math.。- 负数取整易错:
Math.ceil(-1.5)得 -1,Math.floor(-1.5)得 -2;Math.round(-1.5)得 -1(.5 舍入到正无穷方向)。 Math.random()返回[0, 1)的小数,取不到 1。- 随机整数公式:
Math.floor(Math.random() * (M - N + 1)) + N,即Math.floor(Math.random() * (差值 + 1)) + 最小值;不要忘记外层Math.floor,否则拿到的是小数。 - 0~10 要写成
* (10 + 1),否则取不到 10。
常见错误
1. 对象里定义方法用了等号
javascript
let pig = {
sing = function () { console.log('唱歌') } // ✗
}- 现象:直接报语法错误(
Invalid shorthand property initializer),或写出sing: undefined之类的怪结果。 - 原因:对象内部是"键: 值"结构,分隔符只能是英文冒号,
=是赋值运算符,属于对象外部世界的语法。 - 修法:
sing: function () { ... }。记住口诀:对象外用等号,对象内用冒号。
2. 遍历时写 pig.key 拿到 undefined
javascript
for (let key in pig) {
console.log(pig.key) // ✗ 全是 undefined
}- 现象:循环次数对,但每次打印都是
undefined。 - 原因:
pig.key找的是名字叫key的那个属性,而key是变量,它当前保存的是'uname'、'age'这样的字符串。 - 修法:
pig[key]。点后面跟的是写死的属性名,中括号里放的是变量。
3. 中括号里的变量加了引号
javascript
for (let key in pig) {
console.log(pig['key']) // ✗ undefined
}- 现象:和第 2 条一样拿不到值。
- 原因:加了引号就变成字符串字面量
'key',不再是变量,对象里没有叫key的属性。 - 修法:
pig[key],变量不加引号;只有当里面写的是属性名本身(如pig['pig-name'])时才需要引号。
4. 多词属性用点语法,结果 NaN
javascript
console.log(pig.pig-name) // ✗ NaN
console.log(pig['pig-name']) // ✓ 佩奇- 现象:不报错,但输出
NaN,非常隐蔽。 - 原因:
-被当成减号,整句变成pig.pig - name,pig.pig不存在为undefined,undefined - 变量得NaN。 - 修法:含
-、.、空格等特殊字符的属性一律用对象['属性名']。
5. 随机整数范围算错
javascript
Math.floor(Math.random() * 10) + 5 // ✗ 得到 5~14,取不到 15
Math.floor(Math.random() * (15 - 5)) + 5 // ✗ 同上- 现象:边界值永远取不到,或整体偏移。
- 原因:忘了"个数 = 最大值 − 最小值 + 1"里的那个
+1。 - 修法:
Math.floor(Math.random() * (M - N + 1)) + N,写完后代入 N、M 各验一次边界。
6. Math.round 对负数 .5 的预期错误
javascript
Math.round(-1.5) // 得到 -1,不是 -2- 现象:以为"四舍五入"就该远离 0,结果和直觉相反。
- 原因:
round的.5一律向 +∞ 方向舍入,不是按绝对值四舍五入。 - 修法:需要按绝对值四舍五入时写
Math.sign(x) * Math.round(Math.abs(x));只处理正数则无需担心。
练习
练习 1(增删改查) 先定义对象 let car = { brand: 'BMW', price: 30 },然后依次完成:① 打印品牌;② 新增 color: 'red';③ 把 price 改成 25;④ 新增方法 run,调用后打印"跑起来了";⑤ 删除 color,并打印整个对象确认结果。
练习 2(两种取值语法) 定义对象,含一个多词属性 'user-name': '张三' 和普通属性 age: 20。分别用点语法和中括号语法取出这两个值,并说明哪一处必须用中括号、为什么。再用 pig.pig-name 这种错误写法跑一次,观察输出并解释。
练习 3(for in 遍历) 给定 let score = { chinese: 90, math: 88, english: 95 },用 for in 遍历:① 打印所有属性名;② 打印所有分数;③ 求出总分并打印。要求全程不出现写死的属性名。
练习 4(Math + 随机) ① 用 Math.random 写一个函数 randInt(min, max),返回 [min, max] 闭区间内的随机整数;② 用 randInt(1, 10) 生成 100 次,统计每个数字出现的次数,验证 1 和 10 都能被取到;③ 单独验证 Math.round(-1.5)、Math.ceil(-1.5)、Math.floor(-1.5) 三个结果,并写出各自的舍入方向。
练习 5(综合) 用对象描述一个学生:属性含姓名、年龄、成绩数组;方法 average() 返回平均分,方法 info() 打印"姓名 年龄 平均分"。调用两个方法验证结果,再用 for in 遍历该对象并打印所有属性名。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 什么是对象以及对象属性 | 13:01 |
| 2 | 对象方法 | 10:31 |
| 3 | 操作对象 | 09:40 |
| 4 | 查询属性的里另外写法 | 06:05 |
| 5 | 遍历对象 | 14:06 |
小结
- 对象解决的是"数据可读性"问题:数组靠索引,对象靠名字,代价是对象无序。
- 属性和方法的区别只在值是不是函数;语法上唯一的硬约束是内部用冒号、之间用逗号。
- 增和改是同一句语法
obj.x = 值,靠"原来有没有这个属性"区分语义,不需要记两套。 - 点语法用于写死的属性名,中括号用于两类场景:特殊字符属性名 和 变量解析,后者是
for in能工作的前提。 for in拿到的是属性名字符串,取值必须obj[k];k不加引号,这一点是最高频的踩坑点。- 数组遍历用传统
for,for in遍历数组拿到的是字符串索引,容易在做运算时出问题。 Math是内置对象,方法是"拿来就用",重点掌握取整三兄弟的负数表现和Math.floor(Math.random() * (M - N + 1)) + N这一条公式。- 判断自己是否真掌握的标准:不看笔记能写出"对象 + 方法 + 遍历 + 随机数"的完整小案例,并说清每处为什么用点、为什么用中括号。