函数传参技巧
此技巧,为前面所学逻辑中断防止用户没有传入参数,导致输出为NaN的升级方法。
如上图,可以利用或运算符的逻辑中断,如果用户没有传入数据,则x和y都等于0
其实我们可以直接在形参这里设置,x与y等于0,有参数传过来,就等于传过来的数据,没有即也等于0
对象
什么是对象
当我们要储存一类信息,比如一个人,要保存他的姓名,身高,性别,会的技能,我们应该怎么保存它呢?
我们可以用数组,因为数组可以保存各种类型的数据,但有一个致命缺点,就是很难区分,human[180,180,”男”],你无法区分他是是男的,还是喜欢男的哈哈,很难区分。
所以就需要用到对象
静态特征称为属性,动态特征称为方法。
数组是有顺序的,对象是无序的。
对象是一种数据类型,是无序数据的集合,可以详细的描述某个事物。
对象的使用
里面的属性和方法,用逗号隔开
方法后面一般写的是匿名函数
属性名如上图的uname,可以用单/双引号,如写成 ‘uname’
但是一般不添加,除非名称遇到一些特殊符号,但是在json中必须加上。
属性方法名字可以有空格,中横线等,但不代表什么符号都可以(会报错),一般写字母就行了。
console.log与console.dir的区别
一个是直接打印出来,一个是以directory目录的形式显示出来。
属性与方法的访问
属性和方法的访问有两种方法,如下图。
第一种 对象名.属性/方法名
第二种 对象名[‘属性/方法名’]
我们一般用第一种方式,第二种方式在后面会用到,而是必须这样写。
方法的调用
对象.方法名()
如上图有有一个biancheng的方法,调用的时候写obj.biancheng()即可,它本质还是一个函数。
操作对象
1-查,前面已经用到过了,就是 对象.属性/方法名
2-改,直接重新赋值即可
3-增,js中的对象可以动态添加,直接 对象.新属性/方法名=新值
4-删,delete 对象.属性/方法名
遍历对象(for k in 对象)
因为对象没有顺序,不像数组里面的数据都排序了,所以不能通过以前的for循环来遍历
而需要用到 for(let k in 对象)来遍历,k是一个变量,可以随便设置,常用写k
其中这个k就是对象中的方法与属性名字,里面有几个方法和属性,就循环多少次
如上图第一次循环,k===’name’ 第二次循环k===’birthday’ 第三次循环k===‘age’
因为k不是在对象里面的一个属性/方法名字,所以zdq.k是无法取到值的,所以上图出现了undefined
只能通过对象查询的第二种方法, 对象[‘属性/方法名’]来取值。
案例学生信息表(数组对象)
数组对象就是包含多个对象的一个数组
分析:
1-首先把不变的东西通过页面显示出来,如序号,姓名等
2-变化的数据通过遍历数组对象来得到数据,通过for循环来打印tr
3-再把tr中的数据用${}取出对象中的数据替换。
新知识
这里的:not(:first-child)表示,tr中除了第一个tr
<!DOCTYPE html>
<html lang="en">
<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>
<h2>学生信息</h2>
<p>将数据渲染到页面中...</p>
<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: 18, gender: '女', hometown: '山东省' },
{ name: '晓强', age: 18, 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-document.write()和console.log/dir()都是内置对象,我们调用了document对象里面的write方法,console对象里面的log/dir方法
2-alert(),prompt()等是内置函数。
内置对象Math
1-更多的内置对象,可以去w3c或者mdn内查看。
2-内置对象中有方法也有属性,如Math.PI属性,就是3.14xxxxx
3-注意Math的第一个字母大写
Math.random()
它返回的是0-1的随机数,包括0,不包括1
<script>
console.log(Math.PI) // 圆周率 π
console.log(Math.random()) // 随机数 随机抽奖 随机点名
// 返回的是小数 但是能得到 0 得不到 1
// 向上取整 返回的整数
console.log(Math.ceil(1.1)) // ceil 2
console.log(Math.ceil(1.5)) // ceil 2
console.log(Math.ceil(1.9)) // ceil 2
// 向下取整 返回的整数 floor
console.log(Math.floor(1.1)) // floor 1
console.log(Math.floor(1.5)) // floor 1
console.log(Math.floor(1.9)) // floor 1
console.log('-------------------------------')
// round 就近取整( .5往大取证) 返回的整数
console.log(Math.round(1.1)) // round 1
console.log(Math.round(1.5)) // round 2
console.log(Math.round(1.9)) // round 2
console.log('-------------------------------')
console.log(Math.round(-1.1)) // round -1
console.log(Math.round(-1.5)) // round -1
console.log(Math.round(-1.9)) // round -2
// 最大值和最小值
console.log(Math.max(1, 5, 9, 45)) //45
console.log(Math.min(1, 5, 9, 45)) //1
</script>
只需要注意就近取整Math.round(),当数据是负数,遇到 .5 往大取整
如Math.round(1.5)结果为2
但Math.round(-1.5)结果为-1
生成任意范围随机数
这些公式是公理,可以不理解,直接取文档查阅,但是理解可以更好的记忆。
第一个公式:
因为是向下取整,取0-10的整数,一共十一个数字,取十一段范围,如0-0.1的范围给0,0.1-0.2的范围给1,每个数字平均一段“机率”所以是乘11
第三个公式:
1-很明显第三个公式的N是当random取0时用的;
2-当random不等于0,因为后面有+N,所以最少已经是N了,所以只剩下M-N的值,当random随机到最大也永远等于不了1,所以永远取不到公式中的M - N,也就取不到M这个值,所以需要+1来向下取整,得到M
我是这样理解的,可能有错误。
随机点名案例
1-先用公式封装一个取自己设置范围数字的随机数函数
2-把数字长度减1作为max,0作为最小,取得下标,然后输出即可
<script>
let name =['赵云','张飞','关羽','马超','刘备','曹操']
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1))+min
}
document.write(name[getRandom(0,name.length-1)])
</script>
如果取到过的名字,不会再被取到应该怎么做呢?
我的思路:
因为这个名字不一定是在最前面也不一定在最后面,所以需要用splice来删除它即可
综合案例
tips
script标签是可以写在盒子内的,如上图,那么script渲染出的东西,也只会出现在盒子范围内.
分析:
1-这些案例和原先的柱状图案例一样,重在考查对数组对象中的取值
2-我们先写好h5和c3,然后通过for 循环来输出相应对象多个li即可
3-li的页面内容通过数组对象的取值来改变.
拓展
术语
数据类型
简单数据类型存储在栈, 复杂引用数据类型存储在堆(地址存在栈,内容在堆)
对象等赋值,如下
问题:obj2里面的属性改变,obj1也改了,为什么呢?
因为这里obj2被赋予的是obj1的地址,那么两者就指向同一个堆里面的数据
当obj2堆里面的数据改变,自然obj1的也被改变了
数组等引用型数据遇到这种情况也是同理
注意
不管是变量,还是数组,还是对象等等等,它们的声明都会受到作用域的影响,不能跨域使用。