JavaScript-Advanced Days2 Notes
1、toFixed()方法的作用
const num = 12.1
console.log(num.toFixed()) // 12 不填位数默认是返回整数,取整
console.log(num.toFixed(2)) // 12.00
实际上这个方法就是固定保留小数的位数
2、数组的.reduce()方法,聚合方法
const arr = [1, 2, 3] const re = arr.reduce((prev, item) => prev + item) console.log(re)
记住这个.reduce()函数的各个参数含义即可
arr.reduce(function(累计值, 当前元素){}, 起始值)
3、如下代码,解释下.find()方法和every()方法
const arr = [ { name: '小米', price: 1999 }, { name: '华为', price: 3999 }, ] // 1. find 查找 const mi = arr.find(item => item.name === '小米') console.log(mi) // 2. every 每一个是否都符合条件,如果都符合返回 true ,否则返回false const arr1 = [10, 20, 30] const flag = arr1.every(item => item >= 20) console.log(flag)
这段代码展示了两个常用的数组方法:.find() 和 .every()。下面逐一解释它们的概念、作用,并举例说明。
1. .find() 方法
概念:
.find() 方法用于在数组中查找第一个符合条件的元素,并返回该元素。如果没有找到符合条件的元素,则返回 undefined。
作用:
.find() 方法遍历数组中的每个元素,直到找到符合提供的回调函数条件的第一个元素,并返回这个元素。
举例说明:
在代码中,arr 是一个手机对象的数组,其中有 "小米" 和 "华为" 两个对象。我们想要找到名字是 "小米" 的手机。
const mi = arr.find(item => item.name === '小米');
console.log(mi);
- 解释:
.find()会遍历arr数组中的每个对象,找到第一个item.name等于'小米'的对象。 - 输出结果:
{ name: '小米', price: 1999 }
注意: .find() 只返回找到的第一个符合条件的元素,即使有多个符合条件的元素,它也只会返回第一个。
2. .every() 方法
概念:
.every() 方法用于检查数组中的每一个元素是否都符合给定的条件。如果数组中的所有元素都满足条件,返回 true;如果有任何一个元素不满足条件,则返回 false。
作用:
.every() 遍历数组中的每个元素,检查它是否满足条件,如果有任何一个不符合条件,检查会立即停止并返回 false。如果所有元素都符合条件,则返回 true。
举例说明:
在代码中,arr1 是一个数字数组 [10, 20, 30],我们想检查数组中的每个数字是否都大于等于 20。
const flag = arr1.every(item => item >= 20);
console.log(flag);
- 解释:
.every()会遍历arr1数组中的每个数字,检查它是否大于等于 20。 - 在这个例子中,
arr1的第一个元素10不满足item >= 20的条件,因此.every()会立即返回false。 - 输出结果:
false
另一个例子:
假设我们改动一下数组,变成 [20, 30, 40],然后再运行 .every() 方法。
const arr2 = [20, 30, 40]; const flag = arr2.every(item => item >= 20); console.log(flag);
- 在这个例子中,所有元素都满足
item >= 20,所以every()返回true。 - 输出结果:
true
总结:
.find():查找数组中第一个符合条件的元素,并返回该元素。.every():检查数组中的每一个元素是否都符合条件,全部符合返回true,否则返回false。
补充
和 .every() 方法相对的是 .some() 方法,它可以用来判断数组中是否有任意一个元素符合条件。只要有一个元素满足条件,它就返回 true,如果所有元素都不满足条件,才返回 false。
1. .some() 方法
概念:
.some() 方法用于检查数组中的任意一个元素是否符合给定的条件。如果有任何一个元素满足条件,则返回 true;如果所有元素都不满足条件,则返回 false。
举例说明:
我们用一个例子来演示 .some() 的用法:
const arr = [10, 20, 30]; // 检查数组中是否有任意一个元素大于等于 20 const result = arr.some(item => item >= 20); console.log(result); // 输出 true
在这个例子中,arr 数组的第二个元素 20 和第三个元素 30 都满足 item >= 20 的条件,所以 .some() 返回 true。
另一个例子:
如果我们换一个数组来演示,当所有元素都不满足条件时,.some() 返回 false。
const arr2 = [5, 10, 15]; // 检查是否有任意一个元素大于等于 20 const result2 = arr2.some(item => item >= 20); console.log(result2); // 输出 false
- 在这个例子中,数组
arr2中的所有元素都小于20,因此.some()返回false。
总结:
.every():检查数组中的每一个元素是否都符合条件,全部符合返回true,否则返回false。.some():检查数组中的任意一个元素是否符合条件,只要有一个符合就返回true,如果所有元素都不符合则返回false。
.some() 和 .every() 可以说是互补的,一个是“任意符合”,另一个是“全部符合”。
4、关于.join()方法的作用体会。
其实类似python的 “ ”.join()方法,将列表连接成字符串
<script> const spec = { size: '40cm*40cm', color: '黑色' } //1. 所有的属性值回去过来 数组 console.log(Object.values(spec)) // 2. 转换为字符串 数组join('/') 把数组根据分隔符转换为字符串 console.log(Object.values(spec).join('/')) document.querySelector('div').innerHTML = Object.values(spec).join('/') </script>
输出结果:


5、如何理解这里的把伪数组转化为真数组?
在 JavaScript 中,伪数组(也叫类数组对象)是指那些具有数组类似结构的数据类型。它们通常拥有类似数组的 length 属性和按索引存取元素的能力,但它们不是 JavaScript 原生的数组对象,因此不能直接使用数组的方法(如 .pop()、.push() 等)。
伪数组的例子:
像 NodeList、HTMLCollection 这样的 DOM 元素集合是常见的伪数组。它们可以通过索引访问元素,并且有 length 属性,但不能直接调用数组的方法。
具体场景:
在你的代码中,document.querySelectorAll('ul li') 返回的就是一个 NodeList,这是一个伪数组。我们可以像数组一样使用索引来获取其中的元素,也能知道它的长度,但它没有真正的数组方法。
const lis = document.querySelectorAll('ul li');
console.log(lis); // NodeList(伪数组)
如果你尝试对这个伪数组使用数组的 .pop() 方法,会报错,因为 NodeList 并不继承数组的方法。
为什么要把伪数组转化为真数组?
为了能够使用数组的所有方法(如 .pop()、.map()、.filter() 等),你需要把伪数组转换为真数组。
如何转化?
可以使用 Array.from() 方法,它可以将伪数组或者可迭代对象转换为真正的数组。
const liss = Array.from(lis); // 将伪数组 lis 转换为真正的数组 liss
这样 liss 就是一个标准的数组了,你可以对它使用数组的方法,比如 .pop():
liss.pop(); // 现在可以使用数组方法 console.log(liss); // 输出的是真正的数组
总结:
- 伪数组(如
NodeList)和真正的数组结构相似,但不能直接调用数组的方法。 Array.from()方法可以把伪数组转化为真正的数组,之后你就可以使用数组的所有方法。- 转换后,可以使用
.pop()等数组方法对元素进行操作。
举个简单的伪数组和真数组区别的例子:
const lis = document.querySelectorAll('ul li'); // 返回一个 NodeList(伪数组)
console.log(lis.pop()); // 报错,因为 NodeList 没有 pop 方法
const realArray = Array.from(lis); // 把 NodeList 转为真数组
console.log(realArray.pop()); // 可以成功移除最后一个元素
6、关于字符串的常见几个使用方法如下,.split(' , '), .substring(), .startWith(), .includes() 要熟练掌握
这个和python的用法非常类似,迁移成本低。
<script>
// 1. split 把字符串 转换为 数组 和 join() 相反
const str = 'pink,red'
const arr = str.split(',')
console.log(arr)
const str1 = '2022-4-8'
const arr1 = str1.split('-')
console.log(arr1)
// 2. 字符串的截取 substring(开始的索引号[, 结束的索引号])
// 2.1 如果省略 结束的索引号,默认取到最后
// 2.2 结束的索引号不包含想要截取的部分
const str = '今天又要做核酸了'
console.log(str.substring(5, 7))
// 3. startsWith 判断是不是以某个字符开头
const str = 'pink老师上课中'
console.log(str.startsWith('pink'))
// 4. includes 判断某个字符是不是包含在一个字符串里面
const str = '我是pink老师'
console.log(str.includes('pink')) // true
</script>
7、如下这个写法,为什么要先乘以100,然后再除以100呢?
// 3. 合计模块 const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0) // console.log(total) document.querySelector('.amount').innerHTML = total.toFixed(2)
在这段代码中,item.price 是一个小数值,表示商品的价格。代码中先将价格乘以 100,再除以 100,其主要目的是为了避免 浮点数精度问题。
背景:浮点数精度问题
JavaScript 使用的是 IEEE 754 双精度浮点数存储,某些小数值在计算时可能会出现不精确的结果。特别是在涉及加法或乘法时,浮点数会有精度损失。例如,像 0.1 + 0.2 这样的计算,预期结果是 0.3,但在 JavaScript 中得到的是 0.30000000000000004。
乘以 100 再除以 100 的原因
通过将价格先乘以 100,可以将浮点数转换为整数,减少小数部分的计算误差。计算完成后再除以 100,就能恢复到正确的价格格式。
具体步骤:
- 乘以 100:将价格从小数转换为整数的形式,这样可以避免浮点数运算中的精度丢失。
- 计算价格乘以数量的总值:计算完商品的价格与数量后的总价,这时结果相对精确。
- 再除以 100:把之前放大的价格还原到原始小数的精度。
通过一个更复杂的例子来展示不乘以 100 和乘以 100 再除以 100这两种算法的区别。我们会使用浮点数的小数位来展示差异。
例子:价格为 0.1,数量为 3
情况 1:不乘以 100 直接计算
const goodsList = [ { price: 0.1, count: 3 }, ]; const total = goodsList.reduce((prev, item) => prev + item.price * item.count, 0); console.log(total); // 输出结果
计算过程:
- 价格为
0.1,数量为30.1 * 3 = 0.30000000000000004(出现浮点数精度问题)
输出结果:
0.30000000000000004
由于浮点数精度问题,结果不是我们期望的 0.3,而是 0.30000000000000004。
情况 2:乘以 100 再除以 100
const goodsList = [ { price: 0.1, count: 3 }, ]; const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0); console.log(total); // 输出结果
计算过程:
- 价格为
0.1,数量为3- 先乘以
100:0.1 * 100 = 10 - 再乘以数量:
10 * 3 = 30 - 最后再除以
100:30 / 100 = 0.3
- 先乘以
输出结果:
0.3
这次我们得到了正确的结果 0.3,没有出现浮点数精度问题。
总结:
- 不乘以 100 的情况:因为 JavaScript 的浮点数精度问题,计算结果会出现多余的小数位,导致
0.1 * 3变成了0.30000000000000004。 - 乘以 100 再除以 100 的情况:通过将小数转换为整数后计算,再还原为小数,避免了浮点数计算误差,得到了正确的结果
0.3。
这个例子清楚地展示了在处理小数点运算时,乘以 100 再除以 100 的方法可以避免精度问题,确保结果准确。
8、为什么如下标签数据都要放到<form></form>表单里面呢?如果不放在<form></form>标签内又会如何呢?
个人理解:可以把<form></form>先简单当作容器理解。
<!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>注册信息</title> </head> <body> <h1>注册信息</h1> <form action=""> <!-- 表单控件 --> <!-- 个人信息 --> <h2>个人信息</h2> <label>姓名:</label><input type="text" placeholder="请输入真实姓名"> <br><br> <label>密码:</label><input type="password" placeholder="请输入密码"> <br><br> <label>确认密码:</label><input type="password" placeholder="请输入确认密码"> <br><br> <label>性别:</label> <label><input type="radio" name="gender"> 男</label> <label><input type="radio" name="gender" checked> 女</label> <br><br> <label>居住城市:</label> <select> <option>北京</option> <option>上海</option> <option>广州</option> <option>深圳</option> <option>武汉</option> </select> <!-- 教育经历 --> <h2>教育经历</h2> <label>最高学历:</label> <select> <option>博士</option> <option>硕士</option> <option>本科</option> <option>大专</option> </select> <br><br> <label>学校名称:</label><input type="text"> <br><br> <label>所学专业:</label><input type="text"> <br><br> <label>在校时间:</label> <select> <option>2015</option> <option>2016</option> <option>2017</option> <option>2018</option> </select> -- <select> <option>2019</option> <option>2020</option> <option>2021</option> <option>2022</option> </select> <!-- 工作经历 --> <h2>工作经历</h2> <label>公司名称:</label><input type="text"> <br><br> <label>工作描述:</label> <br> <textarea></textarea> <br><br> <!-- 协议 和 按钮 --> <input type="checkbox"><label>已阅读并同意以下协议:</label> <ul> <li><a href="#">《用户服务协议》</a></li> <li><a href="#">《隐私政策》</a></li> </ul> <br><br> <button>免费注册</button> <button type="reset">重新填写</button> </form> </body> </html>
在HTML中,将表单控件放在<form>标签内的主要原因是为了收集用户输入并将其提交到服务器。
<form>标签定义了表单的边界,包含了所有相关的输入控件,确保在提交时,所有的输入数据可以通过指定的action属性发送到服务器。
这样做不仅能提高数据的组织性,也便于实现表单验证和处理提交结果。
如果不将表单控件放在<form>标签内,以下情况会发生:
-
无法提交数据:用户输入的数据无法被收集和提交到服务器。
<form>标签的存在是为了定义提交的上下文,缺少它,浏览器就无法理解哪些数据是属于同一个表单的。 -
无效的输入处理:表单验证和处理(如必填字段的检查)将无法正常工作。许多JavaScript库和浏览器本身的验证功能依赖于表单元素的结构。
-
缺乏组织性:不使用
<form>标签会导致代码结构混乱,难以管理和理解。对于复杂的表单,缺少容器可能会使得维护和修改变得更加困难。 -
默认行为丧失:一些输入控件(例如提交按钮)在
<form>中有特定的默认行为(如提交表单),如果不在<form>内,这些行为将无法正常触发。
总之,使用<form>标签是实现交互式用户输入的标准做法,缺少它会导致功能上的缺失和用户体验的降低。

浙公网安备 33010602011771号