2023/3/13日笔记

104 阅读3分钟

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>