13-1、Iterator是什么
iterator
- iterator:遍历器(迭代器)
- iterator 也是用来遍历的
- Symbol.iterator:可遍历对象的生成方法
什么是 iterator
-Symbol.iterator (可遍历对象的生成方法) -> it (可遍历对象) -> it.next() -> it.next() -> ... (直到 done 为true)
代码案例
<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>13-1、Iterator是什么</title>
</head>
<body>
<script>
// 1.iterator
// iterator:遍历器(迭代器)
// for()
// [1,2].forEach
// new Set().forEach
// iterator 也是用来遍历的
// 2.寻找 iterator
// console.log(iterator);
// console.log([1,2][Symbol.iterator]());
// const it = console.log([1,2][Symbol.iterator]());
// console.log(it);
// 3.使用 iterator
const it = [1,2][Symbol.iterator]();
console.log(it.next()); // {value: 1, done: false}
console.log(it.next()); // {value: 2, done: false}
console.log(it.next()); // {value: undefined, done: true}
console.log(it.next()); // {value: undefined, done: true}
// it:可遍历对象(可迭代对象)
// Symbol.iterator:可遍历对象的生成方法
// 4.什么是 iterator
// Symbol.iterator (可遍历对象的生成方法) -> it (可遍历对象) -> it.next() -> it.next() -> ... (直到 done 为true)
</script>
</body>
</html>
13-2、Iterator解惑
为什么需要 Iterator 遍历器
- 遍历数组:for 循环和 forEach 方法
- 遍历对象:for in 循环
- Iterator 遍历器是一个统一的遍历方式
代码案例
<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>13-2、Iterator解惑</title>
</head>
<body>
<script>
// 1.为什么需要 Iterator 遍历器
// 遍历数组:for 循环和 forEach 方法
// 遍历对象:for in 循环
// Iterator 遍历器是一个统一的遍历方式
// console.log([][Symbol.iterator]());
// console.log({}[Symbol.iterator]);
// 2.如何更方便的使用 Iterator
// Symbol.iterator -> it -> next();
// 我们一般不会直接使用 Iterator 去遍历
// for...of
</script>
</body>
</html>
13-3、for.....of的用法1
for.....of
- for...of 循环只会遍历出那些 done 为 false 时,对应的 value 值
代码案例
<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>13-3、for.....of的用法1</title>
</head>
<body>
<script>
// 1.认识 for... of
const arr = [1,2,3];
const it = arr[Symbol.iterator]();
// console.log(it.next());
// console.log(it.next());
// console.log(it.next());
// console.log(it.next());
// let next = it.next();
// console.log(next);
// while(!next.done) {
// console.log(next.value)
// next = it.next();
// console.log(next);
// }
for(const item of arr) {
console.log(item);
}
// for...of 循环只会遍历出那些 done 为 false 时,对应的 value 值
</script>
</body>
</html>
13-4、for....of的用法2
在 for...of 中取得数组的索引
- keys() 得到的是索引的可遍历对象,可以遍历出索引值
- values() 得到的是值的可遍历对象,可以遍历出值
- entries() 得到的是索引+值组成的数组的可遍历对象
代码案例
<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>13-4、for....of的用法2</title>
</head>
<body>
<script>
// 上接 13-3、for....of的用法1
// 2.与 break,continue 一起使用
// const arr = [1,2,3];
// for(const item of arr) {
// if(item === 2) {
// // break
// continue;
// }
// console.log(item);
// }
// 3.在 for...of 中取得数组的索引
const arr = [1, 2, 3];
// keys() 得到的是索引的可遍历对象,可以遍历出索引值
// console.log(arr.keys());
// for(const key of arr.keys()) {
// console.log(key);
// }
// values() 得到的是值的可遍历对象,可以遍历出值
// for(const value of arr.values()) {
// console.log(value);
// }
// for(const value of arr) {
// console.log(value);
// }
// entries() 得到的是索引+值组成的数组的可遍历对象
// for(const entries of arr.entries()) {
// console.log(entries);
// }
for (const [index, value] of arr.entries()) {
console.log(index, value);
}
</script>
</body>
</html>
13-5、原生可遍历与非原生可遍历
1.什么是原生可遍历
- 只要有 Symbol.iterator 方法,并且这个方法可以生成可遍历对象,就是可遍历的
- 只要可遍历,就可以使用 for...of 循环来统一遍历
原生可遍历的有哪些
- 数组
- 字符串
- Set
- Map
- arguments
- NodeList
非原生可遍历的有哪些
- 一般的对象
- 有 length 和索引值的对象
代码案例
<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>13-5、原生可遍历与非原生可遍历</title>
<style>
p {
user-select: none;
}
</style>
</head>
<body>
<p>1</p>
<p>1</p>
<p>1</p>
<script>
// 1.什么是可遍历
// 只要有 Symbol.iterator 方法,并且这个方法可以生成可遍历对象,就是可遍历的
// 只要可遍历,就可以使用 for...of 循环来统一遍历
// 2.原生可遍历的有哪些
// 数组
// 字符串
// Set
// Map
// arguments
// NodeList
// 遍历一个数组
// for (const item of [1,2,3]) {
// console.log(item);
// }
// 遍历一个字符串
// for (const item of "hi") {
// console.log(item);
// }
// 遍历一个Set
// for (const item of new Set([1,2])) {
// console.log(item);
// }
// 遍历一个Map
// const m = new Map()
// m.set("1",'1').set("2",'2')
// for (const item of m) {
// console.log(item);
// }
// 遍历一个arguments
// let that;
// const fun = function () {that = arguments};
// fun(1,2,3,4)
// for (const item of that) {
// console.log(item);
// }
// 遍历一个NodeList
// for (const item of document.querySelectorAll("p")) {
// console.log(item);
// item.style.color = 'red';
// }
// 3.非原生可遍历的有哪些
// 一般的对象
const person = { sex: 'male', age: 18 };
// console.log(person[Symbol.iterator]());
// {next()}{value,done}
// person[Symbol.iterator] = () => {
// let index = 0;
// return {
// next() {
// index++;
// if (index === 1) {
// return { value:person.age, done:false }
// }else if(index === 2) {
// return{value:person.sex, done:false}
// }else {return{done:true}}
// }
// }
// }
// for(const item of person){console.log(item);}
// for in
// 有 length 和索引值的对象
const obj = {
0: 'alex',
1: 'male',
length: 2
};
// obj[Symbol.iterator] = () => {
// let index = 0;
// return {
// next() {
// let value, done;
// if (index < obj.length) {
// value = obj[index];
// done = false;
// }else {
// value = undefined;
// done = true;
// }
// index++;
// return { value, done }
// }
// }
// }
obj[Symbol.iterator]=Array.prototype[Symbol.iterator];
for (const item of obj){
console.log(item);
}
</script>
</body>
</html>
13-6、使用Iterator的场合
原生可遍历的
- Array 数组
- String 字符串
- Set
- Map
- 函数的 arguments 对象
- NodeList 对象
代码案例
<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>13-6、使用Iterator的场合</title>
</head>
<body>
<script>
// 原生可遍历的
// Array 数组
// String 字符串
// Set
// Map
// 函数的 arguments 对象
// NodeList 对象
// for...of
// 1.数组的展开运算符;
// console.log(...[1,2,3]);
// console.log(1,2,3)
// console.log(...'str');
// console.log(...new Set([1,2,3]));
// console.log(...{}); X
// 2.数组的解构赋值
// const [a, b] = [1, 2];
// const [a, b] = [...[1, 2]];
// const [a,b] ='hi';
// const [a,b] =[...'hi'];
// const [a, b] = new Set([3, 4]);
// console.log(a, b);
// 3.Set 和 Map 的构造函数
// new Set(iteartor);
// new Map(iteartor);
</script>
</body>
</html>
14-1、includes()
includes() :判断字符串中是否含有某些字符
第二个参数表示开始搜索的位置,默认是0
代码案例
<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>14-1、includes()</title>
</head>
<body>
<script>
// 判断字符串中是否含有某些字符
// 1.基本用法
// console.log('abc'.includes("a"));
// console.log('abc'.includes("ab"));
// console.log('abc'.includes("bc"));
// console.log('abc'.includes("ac")); // false
// 2.第二个参数
// 表示开始搜索的位置,默认是0
// console.log('abc'.includes("a"));
// console.log('abc'.includes("a",0));
// console.log('abc'.includes("a",1));
// 3.应用
// https://shengbang.yuque.com/
// https://shengbang.yuque.com/bkc1i3/hguig6/
let url = 'https://shengbang.yuque.com/';
const addUrl = (name) => {
url += url.includes('/', 10) ? '' : '/';
url+=name;
return url;
};
url = addUrl('bkc1i3')
console.log(url);
</script>
</body>
</html>
14-2、padStart()和padEnd()
注意事项
- 原字符串的长度,等于或大于最大长度,不会消减原字符串,字符串补全不生效,返回原字符串
- 用来补全的字符串与原字符串长度之和超过了最大长度,截去超出位数的补全字符串,原字符串不动
- 如果省略第二个参数,默认使用空格补全长度
代码案例
<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>14-2、padStart()和padEnd()</title>
</head>
<body>
<script>
// 补全字符串长度
// 1.基本用法
// console.log('x'.padStart(5,'ab'));
// console.log('x'.padEnd(5,'ab'));
// console.log('x'.padEnd(4,'ab'));
// 2.注意事项
// 原字符串的长度,等于或大于最大长度,不会消减原字符串,字符串补全不生效,返回原字符串
// console.log('xxx'.padStart(2,'ab'));
// console.log('xxx'.padEnd(2,'ab'));
// 用来补全的字符串与原字符串长度之和超过了最大长度,截去超出位数的补全字符串,原字符串不动
// console.log('abc'.padStart(10,'0123456789'));
// console.log('abc'.padEnd(10,'0123456789'));
// 如果省略第二个参数,默认使用空格补全长度
// console.log('x'.padStart(4));
// console.log('x'.padEnd(4));
// 3.应用
// 显示日期格式
// 2020
// 10
// 10
// 2020-10-10
// 2020-01-01
console.log('10'.padStart(2,0));
console.log('1'.padStart(2,0));
</script>
</body>
</html>
14-3、trimStart()和trimEnd()
trimStart()和trimEnd()
- 清除字符串的首或尾空格,中间的空格不会清除
代码案例
<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>14-3、trimStart()和trimEnd()</title>
</head>
<body>
<input type="text" id="user">
<input type="submit" id="users" value="提交">
<script>
// 清除字符串的首或尾空格,中间的空格不会清除
// 1.基本用法
// const s = ' a b c ';
// console.log(s);
// console.log(s.trimStart());
// console.log(s.trimLeft());
// console.log(s.trimEnd());
// console.log(s.trimRight());
// console.log(s.trim());
// 2.应用
const usernameInput = document.querySelector('#user');
const btn = document.querySelector('#users');
btn.addEventListener('click',() => {
console.log(usernameInput.value);
// 验证
console.log(usernameInput.value.trim());
if (usernameInput.value.trim() !== '') {
console.log('可以提交');
}else {
console.log('不可以提交');
}
// 手动提交
},false)
</script>
</body>
</html>
15-1、includes()
基本用法
- 判断数组中是否含有某个成员
- 第二个参数表示搜索的起始位置,默认是0
- 基本遵循严格相等(===),但是对于 NaN 的判断与 === 不同,includes 认为 NaN === NaN
代码案例
<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>15-1、includes()</title>
</head>
<body>
<script>
// 1.基本用法
// 判断数组中是否含有某个成员
// console.log([1,2,3].includes('2')); // false
// console.log([1,2,3].includes(2));
// 第二个参数表示搜索的起始位置,默认是0
// console.log([1,2,3].includes(2,2));
// 基本遵循严格相等(===),但是对于 NaN 的判断与 === 不同,includes 认为 NaN === NaN
// console.log(NaN === NaN);
// console.log([1,2,NaN].includes(NaN));
// 应用
// 去重
// [1,2,1]
const arr = [];
for(const item of [1,2,1]) {
if(!arr.includes(item)){
arr.push(item)
}
}
console.log(arr);
</script>
</body>
</html>
15-2、Array.from()
Array.from()
- 将其他数据类型转换成数组
哪些可以通过 Array.from() 转换成数组
- 所有可遍历的
-
- 数组、字符串、Set、Map、NodeList、arguments
- 拥有 length 属性的任意对象
第二个参数
- 作用类似于数组的 map 方法,用来对每个元素进行处理,将处理后的值放入返回的值
第三个参数
- this的指向
代码案例
<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>15-2、Array.from()</title>
</head>
<body>
<script>
// 将其他数据类型转换成数组
// 1.基本用法
// console.log(Array.from('str'));
// 2.哪些可以通过 Array.from() 转换成数组
// 2.1 所有可遍历的
// 数组、字符串、Set、Map、NodeList、arguments
// console.log(Array.from(new Set([1,2,1])));
// console.log([...new Set([1,2,1])]);
// 2.2拥有 length 属性的任意对象
// const obj = {
// '0':'a',
// '1':'b',
// name:'Alex',
// length:3,
// };
// console.log(Array.from(obj));
// // console.log([...obj]);// X
// 3.第二个参数
// 作用类似于数组的 map 方法,用来对每个元素进行处理,将处理后的值放入返回的值
// console.log([1, 2].map((value) => {
// return value * 2;
// }));
// console.log(Array.from('12', value => value * 2));
// console.log(Array.from('12').map(value => value * 2));
// 4.第三个参数
// 三角函数this就是window
Array.from('12',value => {
console.log(this);
},document)
Array.from('12',function () {
console.log(this);
},document)
</script>
</body>
</html>
15-3、find()和findIndex()
find():找到满足条件的一个立即返回
findIndex():找到满足条件的一个,立即返回其索引
代码案例
<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>15-3、find()和findIndex()</title>
</head>
<body>
<script>
// find():找到满足条件的一个立即返回
// findIndex():找到满足条件的一个,立即返回其索引
// 1.基本用法
// 三角函数的this是window
// console.log(
// [1,5,10,15].find((value,index,arr) => {
// // console.log(value,index,arr);
// console.log(this);
// return value>9;
// },document)
// );
// console.log(
// [1,5,10,15].findIndex((value,index,arr) => {
// // console.log(value,index,arr);
// console.log(this);
// return value>9;
// },document)
// );
// console.log(
// [1,5,10,15].findIndex(function (value,index,arr) {
// // console.log(value,index,arr);
// console.log(this);
// return value>9;
// },document)
// );
// 2.应用
const students = [
{
name: '阿贾',
sex: '男',
age: 16
},
{
name: '多斯',
sex: '男',
age: 16
},
{
name: '克丝',
sex: '女',
age: 16
},
];
console.log(students.find(value => value.sex === '男'))
console.log(students.findIndex(value => value.sex === '男'))
</script>
</body>
</html>
16-1、Object.assign()
Object.assign()
- 用来合并对象
- 可以合并多个对象
注意事项
- 基本数据类型作为源对象
-
- 与对象的展开类似,先转换成对象,再合并
- 同名属性的替换
- 后面的直接覆盖前面的
代码案例
<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>16-1、Object.assign()</title>
</head>
<body>
<script>
// 用来合并对象
// const apple = {
// color: '红色',
// shape: '圆形',
// taste: '甜'
// };
// const pen = {
// color: '黑色',
// shape: '圆柱形',
// use: '写字'
// };
// console.log(Object.assign(apple,pen));
// Object.assign 直接合并到了第一个参数中,返回的就是合并后的对象
// console.log(apple);
// console.log(Object.assign(apple,pen) === apple);
// console.log({...apple,...pen} === apple,{...apple,...pen} === pen);
// 可以合并多个对象
// console.log(Object.assign({},apple,pen));
// console.log(apple);
// console.log({...apple,...pen});
// 2.注意事项
// 2.1.基本数据类型作为源对象
// 与对象的展开类似,先转换成对象,再合并
// console.log(Object.assign({},undefined));
// console.log(Object.assign({},null));
// console.log(Object.assign({},1));
// console.log(Object.assign({},true));
// console.log(Object.assign({},'str'));
// 2.2同名属性的替换
// 后面的直接覆盖前面的
// const apple = {
// color: ['红色','黄色','蓝色'],
// shape: '圆形',
// taste: '甜',
// }
// const pen = {
// color: ['黑色','绿色'],
// shape: '圆柱形',
// use: '写字',
// };
// console.log(Object.assign({},apple,pen));\
// 3.应用
// 合并默认参数和用户参数
const logUser = UserOptions => {
const DEFAULTS = {
username:'ZS',
age:0,
sex:'male'
}
// const options = Object.assign({},DEFAULTS,logUser);
const options = Object.assign({},DEFAULTS,UserOptions);
console.log(options);
};
logUser({});
logUser({username:'Alex'});
</script>
</body>
</html>
16-2、Object.keys()、Object.values()、Object.entries()
与数组类似方法的区别
- 数组的 keys()、values()、entries() 等方法是实例方法,返回的都是 Iterator
- 对象的 Object.keys()、Object.values() 、Object.entries() 等方法是构造函数方法,返回的是数组
使用 for...of 循环遍历对象
- Object.keys()/values()/entries() 并不能保证顺序一定是你看到的样子,这一点和 for in 是一样的
代码案例
<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>16-2、Object.keys()、Object.values()、Object.entries()
</title>
</head>
<body>
<script>
// 1.基本用法
// const person = {
// name: 'alex',
// age: 18,
// };
// console.log(Object.keys(person));
// console.log(Object.values(person));
// console.log(Object.entries(person));
// 2.与数组类似方法的区别
// console.log([1,2].keys());
// console.log([1,2].values());
// console.log([1,2].entries());
// console.log(person.keys());
// 数组的 keys()、values()、entries() 等方法是实例方法,返回的都是 Iterator
// 对象的 Object.keys()、Object.values() 、Object.entries() 等方法是构造函数方法,返回的是数组
// 3.使用 for...of 循环遍历对象
const person = {
name: 'alex',
age: 18,
};
// for(const key of Object.keys(person)) {
// console.log(key);
// }
// for(const value of Object.values(person)) {
// console.log(value);
// }
// for(const entrie of Object.entries(person)) {
// console.log(entrie);
// }
// for(const [key,value] of Object.entries(person)) {
// console.log(key,value);
// }
// Object.keys()/values()/entries() 并不能保证顺序一定是你看到的样子,这一点和 for in 是一样的
</script>
</body>
</html>