JavaScript 基础(5) - 笔记
知道对象数据类型的特征,能够利用数组对象渲染页面
- 理解什么是对象,掌握定义对象的语法
- 掌握数学对象的使用
1 对象
对象是 JavaScript 数据类型的一种,之前已经学习了数值类型、字符串类型、布尔类型、undefined。对象数据类型可以被理解成是一种数据集合。它由属性和方法两部分构成。
1.1 对象是什么
对象(object):JavaScript里的一种数据类型。
可以理解为是一种无序的数据集合,注意数组是有序的数据集合。
用来描述某个事物,例如描述一个人
- 人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
- 如果用多个变量保存则比较散,用对象比较统一
1.2 语法
1.对象声明语法
let 对象名 = {
}
let 对象名 = new object()
例如:
// 声明了一个person的对象
// {}是对象字面量
let person = {
}
2.对象有属性和方法组成
let 对象名= {
属性名: 属性值,
方法名: 函数
}
声明一个对象类型的变量与之前声明一个数值或字符串类型的变量没有本质上的区别。
// 声明字符串类型变量
let str = 'hello world!'
// 声明数值类型变量
let num = 199
// 声明对象类型变量,使用一对花括号
// user 便是一个对象了,目前它是一个空对象
let user = {
}
1.3 属性和访问
数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。
- 属性都是成 对出现的,包括属性名和值,它们之间使用英文
:
分隔。 - 多个属性之间使用英文
,
分隔。 - 属性就是依附在对象上的变量(外面是变量,对象内是属性)。
- 属性名可以使用
""
或''
,一般情况下省略,除非名称遇到特殊符号如空格、中横线等。
// 通过对象描述一个人的数据信息
// person 是一个对象,它包含了一个属性 name
// 属性都是成对出现的,属性名 和 值,它们之间使用英文 : 分隔
let person = {
name: '小明', // 描述人的姓名
age: 18, // 描述人的年龄
stature: 185, // 描述人的身高
gender: '男', // 描述人的性别
}
声明对象,并添加了若干属性后,可以使用 .
或 []
获得对象中属性对应的值,我称之为属性访问。
// 通过对象描述一个人的数据信息
// person 是一个对象,它包含了一个属性 name
// 属性都是成对出现的,属性名 和 值,它们之间使用英文 : 分隔
let person = {
name: '小明', // 描述人的姓名
age: 18, // 描述人的年龄
stature: 185, // 描述人的身高
gender: '男', // 描述人的性别
};
// 访问人的名字
console.log(person.name) // 结果为 小明
// 访问人性别
console.log(person.gender) // 结果为 男
// 访问人的身高
console.log(person['stature']) // 结果为 185
// 或者
console.log(person.stature) // 结果同为 185
扩展:也可以动态为对象添加属性,动态添加与直接定义是一样的,只是语法上更灵活。
// 声明一个空的对象(没有任何属性)
let user = {
}
// 动态追加属性
user.name = '小明'
user['age'] = 18
// 动态添加与直接定义是一样的,只是语法上更灵活
1.3.1 属性-查
声明对象,并添加了若干属性后,可以使用,获得对象中属性对应的值,我称之为属性访问。
语法:对象名.属性
简单理解就是获得对象里面的属性值。
let person = {
uname: 'pink尘缘',
age: 18,
gender: '女'
}
console.log(person.uname)
console.log(person.age)
console.log(person.gender)
1.3.2 属性-改
语法:对象名.属性 = 新值
let person = {
uname: 'pink尘缘',
age: 18,
gender: '女'
}
person.gender = '男'
console.log(person.gender) // 修改了为男
console.log(person)
对于多词属性或则 - 等属性,点操作就不能用了。
我们可以采取:对象['属性'] 方式,单引号和双引号都阔以。
// 查总结:
// (1)对象名.属性名 obj.age
console.log(obj.num)
// (2)对象名['属性名'] obj['age']
console.log(obj['num'])
1.3.3 属性-增
语法:对象名.属性 = 新值
let person = {
uname: 'pink尘缘',
age: 18,
gender: '女'
}
person.hobby = '足球'
console.log(person)
1.3.4 属性-删(了解)
语法:delete 对象名.属性
let person = {
uname: 'pink尘缘',
age: 18,
gender: '女'
}
delete person.age // 删除 age属性
console.log(person)
1.4 方法和调用
数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。
let person = {
uname: 'andy',
sayHi: function() {
document.write('hi~~~')
}
}
- 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
- 多个属性之间使用英文
,
分隔 - 方法是依附在对象中的函数
- 方法名可以使用
""
或''
,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
// 方法是依附在对象上的函数
let person = {
name: '小红',
age: 18,
// 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
singing: function () {
console.log('两只老虎,两只老虎,跑的快,跑的快...')
},
run: function () {
console.log('我跑的非常快...')
}
}
声明对象,并添加了若干方法后,可以使用 .
或 []
调用对象中函数,我称之为方法调用。
也可以添加形参和实参。
let person = {
uname: 'andy',
sayHi: function() {
document.write('hi~~~')
}
}
// 对象名.方法名
person.sayHi()
注意:千万别忘了给方法名后面加小括号。
// 方法是依附在对象上的函数
let person = {
name: '小红',
age: 18,
// 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
singing: function () {
console.log('两只老虎,两只老虎,跑的快,跑的快...')
},
run: function () {
console.log('我跑的非常快...')
}
}
// 调用对象中 singing 方法
person.singing()
// 调用对象中的 run 方法
person.run()
扩展:也可以动态为对象添加方法,动态添加与直接定义是一样的,只是语法上更灵活。
// 声明一个空的对象(没有任何属性,也没有任何方法)
let user = {
}
// 动态追加属性
user.name = '小明'
user.['age'] = 18
// 动态添加方法
user.move = function () {
console.log('移动一点距离...')
}
注:无论是属性或是方法,同一个对象中出现名称一样的,后面的会覆盖前面的。
1.5 null
null 也是 JavaScript 中数据类型的一种,通常只用它来表示不存在的对象。使用 typeof 检测类型它的类型时,结果为 object
。
1.5.1 遍历对象
for 遍历对象的问题:
- 对象没有像数组一样的length属性,所以无法确定长度。
- 对象里面是无序的键值对,没有规律。不像数组里面有规律的下标。
let obj = {
uname: 'pink'
}
for(let k in obj) {
// k 属性名 字符串 带引号 obj.'uname' k === 'uname'
// obj[k] 属性值 obj['uname'] obj[k]
}
let obj = {
uname: 'andy',
age: 18,
sex: '男'
}
for (let key in obj) {
console.log(key) // 打印属性名
console.log(obj[key]) // 打印属性值
}
- 一般不用这种方式遍历数组、主要是用来遍历对象。
- for in语法中的 k 是一个变量,在循环的过程中依次代表对象的属性名。
- 由于 k 是变量,所以必须使用 [] 语法解析。
- 一定记住:k 是获得对象的属性名,对象名[k] 是获得 属性值。
- for in 不提倡遍历数组 因为 k 是 字符串。
案例:遍历数组对象
需求:请把下面数据中的对象打印出来:
//定义一个存储了若干学生信息的数组
let students = [
{ name: '小明', age: 18, gender: '男', hometown: '河北省' },
{ name: '小红', age: 19, gender: '女', hometown: '河南省' },
{ name: '小刚', age: 17, gender: '男', hometown: '山西省' },
{ name: '小丽', age: 18, gender: '女', hometown: '山东省' },
]
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++) {
// console.log(i) // 下标索引号
// console.log(students[i]) // 每个对象
console.log(students[i].name)
console.log(students[i].hometown)
}
需求根据以上数据渲染生成表格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<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>
<h2>学生信息</h2>
<p>将数据渲染到页面中...</p>
<table>
<caption>学生列表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<!-- script写到这里 -->
<script>
// 1. 数据准备
let students = [
{
name: '小明', age: 18, gender: '男', hometown: '河北省' },
{
name: '小红', age: 19, gender: '女', hometown: '河南省' },
{
name: '小刚', age: 17, gender: '男', hometown: '山西省' },
{
name: '小丽', age: 18, gender: '女', hometown: '山东省' },
]
// 2. 渲染页面
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>
2 内置对象
回想一下我们曾经使用过的 console.log
,console
其实就是 JavaScript 中内置的对象,该对象中存在一个方法叫 log
,然后调用 log
这个方法,即 console.log()
。
除了 console
对象外,JavaScritp 还有其它的内置的对象@@@@@
2.1 Math
Math
是 JavaScript 中内置的对象,称为数学对象,这个对象下即包含了属性,也包含了许多的方法。
2.1.1 属性
- Math.PI,获取圆周率
// 圆周率
console.log(Math.PI);
2.1.2 方法
2.1.2.1 内置对象-生成任意范围随机数
Math.random() 随机数函数,返回一个0 - 1 之间,并且包括1的随机小数 [0,1)
如何生成 0 - 10的随机数呢?
// floor 为了取整 Math.floor(Math.random() * (10 + 1))
let arr = ['red', 'green', 'blue'] let random = Math.floor(Math.random() * arr.length) console.log(arr[random])
如何生成5 - 10 的随机数?
Math.floor(Math.random() * (5 + 1)) + 5
如何生成N - M 之间的随机数
Math.floor(Math.random() * (M - N + 1)) + N
案例:随机点名
let arr = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操']
// 1. 得到一个随机数, 作为数组的索引号, 这个随机数是 0 ~ 6
let random = Math.floor(Math.random() * arr.length)
// 2. 页面输出里面的元素
document.write(arr[random])
案例:随机点名案例改进
需求:请把['赵云',黄忠',关羽',张飞',马超',刘备,曹操]随机显示一个名字到页面中,但是不
允许重复显示。
let arr = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操']
// 1. 得到一个随机数, 作为数组的索引号, 这个随机数是 0 ~ 6
let random = Math.floor(Math.random() * arr.length)
// 2. 页面输出里面的元素
document.write(arr[random])
// 3. splice(起始位置(下标), 删除几个元素)
arr.splice(random, 1)
console.log(arr)
案例:猜数字游戏
需求:程序随机生成1~10之间的一个数字,用户输入一个数字
①:如果大于该数字,就提示,数字猜大了,继续猜
②:如果小于该数字,就提示,数字猜小了,继续猜
③:如果猜对了,就提示猜对了,程序结束
// 1. 随机生成一个数字 1~10
function getRandom(N, M) {
return Math.floor(Math.random() * (M - N + 1)) + N
}
let random = getRandom(1, 10)
// 2. 设定三次 三次没猜对就直接退出
let flag = true // 开关变量
for (let i = 1; i <= 3; i++) {
let num = +prompt('请输入1~10之间的一个数字:')
if (num > random) {
alert('您猜大了,继续')
} else if (num < random) {
alert('您猜小了,继续')
} else {
flag = false
alert('猜对了')
break
}
}
if (flag) {
alert('次数已经用完')
}
案例:生成随机颜色
需求:该函数接收一个布尔类型参数,表示颜色的格式是十六进制还是rgb格式。
①:如果参数传递的是true或者无参数,则输出一个随机十六进制的颜色
②:如果参数传递的是false,则输出一个随机rgb的颜色
③:格式:function getRandomColor(flag){
}
console.log(getRandomColor(true)) //#ffffff
console.log(getRandomColor(false)) //rgb(255,255,255)
分析:
提示:16进制颜色格式为:#ffffff'其中f可以是任意0-f之间的字符,需要用到数组,
let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
提示:rgb颜色格式为: 'rgb(255,255,255)' 其中255可以是任意0-255之间的数字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<div></div>
<script>
// 1. 自定义一个随机颜色函数
function getRandomColor(flag = true) {
if (flag) {
// 3. 如果是true 则返回 #ffffff
let str = '#'
let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
// 利用for循环随机抽6次 累加到 str 里面
for (let i = 1; i <= 6; i++) {
// 每次要随机从数组里面抽取一个
// random 是数组的索引号 是随机的
let random = Math.floor(Math.random() * arr.length)
str += arr[random]
}
return str
} else {
// 4. 否则是 false 则返回 rgb(255, 255, 255)
let r = Math.floor(Math.random() * (255 + 1))
let g = Math.floor(Math.random() * (255 + 1))
let b = Math.floor(Math.random() * (255 + 1))
return `rgb(${r}, ${g}, ${
b})`
}
}
// 2. 调用函数 getRandomColor(布尔值)
console.log(getRandomColor(false))
console.log(getRandomColor(true))
console.log(getRandomColor())
const div = document.querySelector('div')
div.style.backgroundColor = getRandomColor()
</script>
</body>
</html>
2.1.2.2 拓展-术语解释
术语 | 解释 | 举例 |
---|---|---|
关键字 | 在JavaScript中有特殊意义的词汇 | let、var、function、if、else、switch、case、break |
保留字 | 在目前的JavaScript中没有意义,但未来可能会具有特殊意义的词汇 | int、short、long、char |
标识(标识符) | 变量名、函数名的另一种叫法 | 无 |
表达式 | 能产生值的代码,一般配合运算符出现 | 10 + 3、age >= 18 |
语句 | 一般可执行的代码 | if() for() |
2.1.2.3 拓展-基本数据类型和引用数据类型
简单类型又叫基本数据类型或者值类型,复杂类型又叫引用类型。
值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型string,number,boolean,undefined,null
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面
1.简单数据类型的内存分配
- 值类型(简单数据类型):string,number,boolean,undefined,null
- 值类型变量的数据直接存放在变量(栈空间)中
2.复杂类型的内存分配
- 引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
- 引用类型变量(栈空间)里面存放的是地址,真正的对象实例存放在堆空间中
- Math.random,生成 0 到 1 间的随机数
// 0 ~ 1 之间的随机数, 包含 0 不包含 1
Math.random()
- Math.ceil,数字向上取整
// 舍弃小数部分,整数部分加1
Math.ceil(3.4)
- Math.floor,数字向下取整
// 舍弃小数部分,整数部分不变
Math.floor(4.68)
- Math.round,四舍五入取整
// 取整,四舍五入原则
Math.round(5.46539)
Math.round(4.849)
- Math.max,在一组数中找出最大的
// 找出最大值
Math.max(10, 21, 7, 24, 13)
- Math.min,在一组数中找出最小的
// 找出最小值
Math.min(24, 18, 6, 19, 21)
- Math.pow,幂方法
// 求某个数的多少次方
Math.pow(4, 2) // 求 4 的 2 次方
Math.pow(2, 3) // 求 2 的 3 次方
- Math.sqrt,平方根
// 求某数的平方根
Math.sqrt(16)
数学对象提供了比较多的方法,这里不要求强记,通过演示数学对象的使用,加深对对象的理解。
3 总结:
splice() 方法用于添加或删除数组中的元素。
注意:这种方法会改变原始数组。
- 删除数组:
splice(起始位置, 删除的个数)
比如:1
let arr = ['red', 'green', 'blue']
arr.splice(1,1) // 删除green元素
console.log(arr) // ['red, 'blue']
- 添加元素
splice(起始位置,删除个数,添加数组元素)
let arr = ['red', 'green', 'blue']
//arr.splice(1, 0, 'pink') // 在索引号是1的位置添加 pink
//console.log(arr) // ['red', 'pink', 'green', 'blue']
arr.splice(1, 0, 'pink', 'hotpink') // 在索引号是1的位置添加 pink hotpink
console.log(arr) // ['red', 'pink', 'hotpink', 'green', 'blue']
3.1 变量声明
- 变量声明有三个 var let 和 const
- 我们应该用那个呢?
- 首先 var 先排除,老派写法,问题很多,可以淘汰掉...
- let or const ?
建议:const优先,尽量使用const,原因是:
- const语义化更好
- 很多变量我们声明的时候就知道他不会被更改了,那为什么不用constl呢?
- 实际开发中也是,比如react框架,基本const
建议:有了变量先给const,如果发现它后面是要被修改的,再改为let