一、对象
1、对象概念
- 对象(object):JavaScript里的一种数据类型
- 可以理解为是一种无序的数据集合
- 用来描述某个事物,例如描述一个人
人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
如果用多个变量保存则比较散,用对象比较统一 - 比如描述 班主任 信息:
静态特征 (姓名, 年龄, 身高, 性别, 爱好) => 可以使用数字, 字符串, 数组, 布尔类型等表示
动态行为 (点名, 唱, 跳, rap) => 使用函数表示
2、对象使用
(1)对象声明语法
(2) 对象有属性和方法组成
属性:信息或叫特征(名词)。 比如 手机尺寸、颜色、重量等…(变量)
方法:功能或叫行为(动词)。 比如 手机打电话、发短信、玩游戏…(函数)
- 属性
数据描述性的信息称为属性
属性都是成对出现的,包括属性名和值,它们之间使用英文 : 分隔
多个属性之间使用英文 , 分隔
属性就是依附在对象上的变量(外面是变量,对象内是属性)
属性名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
-
属性访问
声明对象,并添加了若干属性后,可以使用 . 或 [] 获得对象中属性对应的值,称之为属性访问。
-
方法
数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。
方法是由方法名和函数两部分构成,它们之间使用 : 分隔
多个属性之间使用英文 , 分隔
方法是依附在对象中的函数
方法名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
- 方法调用
声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,称之为方法调用
对象方法调用可以传递参数
3、操作对象
(1)增删改查
- 增加属性,可以动态为对象添加属性
- 增加方法,动态为对象添加方法
添加属性/方法就是:对象如果有这个属性/方法相当于重新赋值/定义;对象如果没有这个属性/方法相当于动态添加一个属性/方法
4、遍历对象
注意,k就是一个循环变量,第一次循环等于’uname‘,第二次等于’age‘……
这里,使用 for in 遍历,通过 k 获得对象的属性名, 对象名[k] 获得 属性值
不能用对象名.[k]或者对象名.[‘k’] 遍历获得属性值,因为k是变量不是属性名,属性中只有uname等,没有一个叫k的。要与查询对象区分开。
5、内置对象
(1)内置对象概念
JavaScript内部提供的对象,包含各种属性和方法给开发者调用,如document.write()、console.log()
(2) 内置对象Math
- Math对象是JavaScript提供的一个“数学高手”对象
- 提供了一系列做数学运算的方法
- 方法有:
random:生成0-1之间的随机数(包含0不包括1)
ceil:向上取整
floor:向下取整
max:找最大数
min:找最小数
pow:幂运算
abs:绝对值 - 可以在 mdn 中查找具体方法的介绍
(3)生成任意范围随机数
- 如何生成0-10的随机数呢?
Math.floor(Math.random() * (10 + 1))
- 如何生成5-10的随机数?
Math.floor(Math.random() * (5 + 1)) + 5
- 如何生成N-M之间的随机数(包括N、M)
Math.floor(Math.random() * (M - N + 1)) + N
一般封装在函数中,可以直接调用:
<script>
function getRandom(x,y){
return Math.floor(Math.random()*(y-x+1))+x
}
let r = getRandom(1,10) //随机返回1-10的整数
console.log(r)
</script>
二、案例–学生信息表(对象)
请把下面数据中的对象打印出来:
// 定义一个存储了若干学生信息的数组
let students = [
{name: ‘小明’, age: 18, gender: ‘男’, hometown: ‘河北省’},
{name: ‘小红’, age: 19, gender: ‘女’, hometown: ‘河南省’},
{name: ‘小刚’, age: 17, gender: ‘男’, hometown: ‘山西省’},
{name: ‘小丽’, age: 18, gender: ‘女’, hometown: ‘山东省’}
]
① 首先,不管具体的数据内容,先把表格样子整出来(html+css)
<!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;
border-collapse: collapse; //合并表格框
}
caption{
font-weight: 600;
font-size: 18px;
margin-bottom: 20px;
}
th,td{
height: 40px;
border:1px solid #ccc;
cursor: pointer;
}
tr:first-child{
background-color: #ddd;
}
tr:not(first-child):hover{ //只有第一行鼠标悬停不会变灰色
background-color: #eee;
}
</style>
</head>
<body>
<table>
<caption>学生信息表</caption> //内容先随便写点固定的占位
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
</table>
</body>
</html>
做完如下,样子有了,不过里面的数据是没有意义的。
② 利用JS把数据传进去,能动态改变
因为要遍历数组,肯定需要用到循环,循环不能放在document.write( )中,所以输出分为三块,首先打印头部和尾部两块,也就是循环前面和后面的内容。
其次通过循环打印表格每一位同学信息,先循环,在循环里面打印。
document.write()中的内容结构和原来用来的静态数据结构类似,比如都是
<table>
里面放<caption>
,然后<tr>
等,所以要先用静态数据将格式做出来,再填入动态数据。
完整代码:
<!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;
border-collapse: collapse; //合并表格框
}
caption{
font-weight: 600;
font-size: 18px;
margin-bottom: 20px;
}
th,td{
height: 40px;
border:1px solid #ccc;
cursor: pointer;
}
tr:first-child{
background-color: #ddd;
}
tr:not(first-child):hover{ //除了第一行鼠标悬停都变灰色
background-color: #eee;
}
</style>
</head>
<body>
<script>
let students = [
{name: '小明', age: 18, gender: '男', hometown: '河北省'},
{name: '小红', age: 19, gender: '女', hometown: '河南省'},
{name: '小刚', age: 17, gender: '男', hometown: '山西省'},
{name: '小丽', age: 18, gender: '女', hometown: '山东省'},
{name: '小胡', age: 19, gender: '女', hometown: '河南省'},
]
// 第一步 打印表格的头部和尾部
document.write(`
<table>
<caption>学生信息表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>`)
// 中间遍历行数
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>`)
}
// 尾部
document.write(`</table>`)
</script>
</body>
</html>
三、案例–猜数字游戏(随机数)
需求:程序随机生成 1~10 之间的一个数字,用户输入一个数字
①:如果大于该数字,就提示,数字猜大了,继续猜
②:如果小于该数字,就提示,数字猜小了,继续猜
③:如果猜对了,就提示猜对了,程序结束
<script>
function getRandom(x,y){
return Math.floor(Math.random()*(y-x+1))+x
}
let r = getRandom(1,10)
while(true){
let n = prompt('请输入猜的数')
if(n>r){
alert('猜大了')
}
else if (n<r){
alert('猜小了')
}
else {
alert('对了')
break // 退出循环
}
}
</script>
四、综合案例–学成在线
(总体采用的策略还是先写好html和css,然后在利用JS添加数据渲染)
在前面的综合案例,如柱状图里面,有循环动态加入数据的,但是因为for循环不能写在
document.write()
中,所以采用的是先写盒子的上一半<div>
,再写下一半</div>
,这样就能将for循环夹在中间(浏览器显示的时候就会在盒子里面)且没写入document.write()
。
但是这个案例盒子太多,结构比较复杂,如下
这样拆盒子写法太繁琐了,有第二种方法,将<script>
写在需要渲染的盒子标签里面。
在这里头部(精品推荐+查看全部)都不用传入数据动态改变,需要渲染的只有下面具体的课程,也就是 ul
中的 li
。于是就在 ul
标签里面放入 script
,利用JS语言循环传入数据。(data为存储数据的数组)。
完整代码:
<!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>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="box">
<div class="head">
<h3>精品推荐</h3>
<p>查看全部</p>
</div>
<div class="body">
<ul>
<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>
<img src="${data[i].src}" alt=""></img>
<h4>${data[i].title}</h4>
<div class="info">
<span>高级</span> •
<span>${data[i].num}</span>人在学习
</div>
</li>
`)
}
</script>
</ul>
</div>
</div>
</body>
</html>
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
img{
width: 100%;
}
body{
background-color: #f3f5f7;
}
.box{
width: 1200px;
margin: 30px auto;
}
.box .head{
display: flex;
justify-content: space-between;
margin-bottom: 15px;
}
.box .head h3{
font-size: 20px;
color: #494949;
}
.box .head p{
margin-right: 30px;
margin-top: 10px;
font-size: 12px;
color: #a5a5a5;
}
.box .body ul{
display: flex;
flex-wrap: wrap;
}
.box .body ul li{
width: 228px;
height: 270px;
background-color: #FFF;
margin-right: 15px;
margin-bottom: 15px;
transition: all 0.3s;
}
.box .body ul li:nth-child(6n){
margin-right: 0;
}
.box .body ul li:hover{
margin-top:-8px;
box-shadow: 2px 2px 2px 2px rgba(0,0,0,.3);
}
.box .body ul li h4{
margin: 20px 20px 20px 25px;
font-size: 14px;
color: #050505;
font-weight: 400;
}
.box .body ul li .info{
margin-left: 25px;
font-size: 12px;
color: #999;
}
.box .body ul li .info span{
color: #ff7c2d;
}
五、方法总结:
通过案例学生信息表总结方法,数据渲染前的代码:
<table>
<caption>学生信息表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<tr>
<td>1</td>
<td>小马</td>
<td>12</td>
<td>男</td>
<td>河南</td>
</tr>
<tr>
<td>2</td>
<td>小马</td>
<td>12</td>
<td>男</td>
<td>河南</td>
</tr>
</table>
写好html+css后,用数据渲染,可以有两种方法,第一种就是之前用的,所有代码都写在
script
中,把盒子标签<div></div>
拆开用document.write
写出来,就能在中间通过循环使用数据渲染,这种方法比较麻烦,适合盒子嵌套少的结构简单的,如下:
第二种是找到需要数据渲染的盒子标签,在里面放入script
标签,而对于其他的不需要数据渲染的盒子,就不用管。这种方法适合结构复杂盒子嵌套很多的。如下:(左边是原来静态的没渲染数据的代码,从中可以发现,需要渲染的是从第二个<tr>
开始的全部<tr>
,于是在这里放入script
。)
六、拓展、术语认识
1、数据类型
- 分为简单数据类型和复杂数据类型
- 简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型,如string ,number,boolean,undefined,null
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型,如通过 new 关键字创建的对象(系统对象、自定义对象), Object、Array、Date等
2、数据类型的存储方式
-
简单数据类型存放到栈里面
栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
-
引用数据类型存放到堆里面
堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
3、例子
第一个结果为10,第二个结果为20
原因:
第一个是简单数据类型,就存放在栈中,num1=10,就是num1指向栈中存的10,同理num2,改变num2的值,只改变了num2在栈中存放的10,所以num1值不变;
第二个是复杂数据类型,obj1指向栈中一块地址,然后该地址指向堆中一块区域,存放的obj1的值。obj2 = obj1,即在栈中,obj2和obj1一样,因为复杂数据类型栈中存放的是地址,所以obj2和obj1指向了一个地址,然后该地址指向堆中一个数据,改变obj2的值,该数据就变了,obj1指向的也是该数据,所以也变了。