1 jquery

1.1 初始化函数

01.介绍
    a.window.onload
        执行时间:须等待网页中所有的内容加载完毕后(图片、flash、视频等)才能执行
        编写个数:一页面不能同时编写多个
        简化写法:无
    b.$(document).ready()
        执行时间:网页中所有DOM文档结构绘制完毕后即刻执行,可能与DOM元素关联的内容(图片、flash、视频等)并没有加载完
        编写个数:同一页面能同时编写多个
        简化写法:$(function}{}

02.代码
    <html>
    <head>
        <title>初始化函数:两种方式</title>
        <!-- 引入jQuery-->
        <script type="text/javascript" src="js/jquery-3.3.1.js" ></script>

        <!--使用引入jQuery-->
        <script type="text/javascript">
            //$(document).ready():初始化函数,当网页中的dom元素(不包含图片、视频、资源)全部加载完毕后,立刻执行
            //$(document).ready():同一个页面能同时编写多个
            $(document).ready(function(){
                alert("hello world");
                alert("hello world2");
            });

            //$(document).ready():简化形式$(function)(){}
            $(function(){
                alert("hello function...");
            });

            //$等价于jQuery
            jQuery(function(){
                alert("hello function2...");
            });


            //window.onload:初始化函数,当网页中的dom元素(关联图片、视频、资源)全部加载完毕后,立刻执行
            //window.onload:同一页面不能同时编写多个
            function init(){
                alert("hello jquery");
            }

        </script>
    </head>
        <body onload="init()">
        </body>
    </html>

1.2 DOM与jQuery转换

01.DOM模型:将html、xml等文档结构的标签语言,都可以看成DOM模型

02.DOM节点有三种类型:
    ①元素节点:<html><ul>..<p>
    ②属性节点:titlesrcalt
    ③文本节点:文本节点

03.DOM对象:
    ①概念层面:以上三种节点类型的具体对象就是DOM对象
    ②使用层面:凡是JavaSCript能够直接操作的对象就是DOM对象
              例如,vartitle=document.getElementByld("myTitile");
              通过js获取到的title对象就是一个dom对象(就是<p>对象)

04.jQuery对象:
    使用层面:凡是jQuery能够直接操作的对象,就是jQuery对象
    例如:var$title=$("#myTitile");通过jquery获取到的$title就是一个jquery对象

05.总结
    ①同样一个元素,即可以成为一个dom对象(javascript对象),也可以成为一个jquery对象
    ②dom对象只适用于js的各种语法(函数、属性),而jquery对象只用于jquery的各种语法(函数、属性)
    ③dom对象和jquery对象的各自独立
     例如:
     title是dom对象,因此可以使用js属性或方法title.innerHTML
     Stitle是jquery对象,因此可以使用jquery属性或方法$title.html0

06.DOM对象与jQuery对象转换
    DOM对象->jQuery对象:jQuery工厂$(DOM对象)
    jQuery对象->DoM对象:基础(jquery对象默认是一个数组或集合:dom对象默认是一个单独的对象)
                        ①数组->单独对象:jquery对象[0]
                        ②集合->单独对象:jquery对象.get(0)

1.3 选择器

01.基本选择器
    1.标签选择器:$("标签名")                                          $("p").html()
    2.类选择器:$(".class值")                                          $(".myTitile1").html()
    3.id选择器:$("#id值")                                             $("#myTitile2").html()
    4.并集选择器:逗号,(或,可以同时选中多个)                         $(".myTitile1,#myTitile2,.myTitile3").length
    5.交集选择器:直接拼写,(同时存在,只能选中一个,不能出现歧义)      $("p#myTitile2").length
    6.全局选择器:选中全部的元素                                        $("*").length

02.层次选择器
    1.相邻同辈选择器(只取后面的元素有效):+      $("选择器1+选择器2")   $("#b+li").length
    2.通用同辈选择器(只取后面的元素有效):~      $("选择器1~选择器2")   $("#b~li").length
    3.后代选择器(子代、孙子代...):空格          $("选择器1 选择器2")   $("body li").length
    4.子代选择器(子代):>                       $("选择器1>选择器2")   $("body>ul>li").length

03.属性选择器
    1.$("[属性名]")           全部
    2.$("[class=xxx]")       等于,也可以加上'',$("[class='xxx']")
    3.$("[class!=a]")        不等于:包括两种情况,一是有class值但不是a
    4.$("[class^=a]")        class以a开头的元素
    5.$("[class$=a]")        class以a结尾的元素
    6.$("[class*=a]")        class有a的全部元素

04.过滤选择器(从0开始,0代表偶数)
    过滤选择器的一些方法 和 其他函数类型,
    例如,可以$("ul>li:first") 等价于 $("ul>li").first()
    有些不同,例如,可以$("ul>li:odd"); 错误$("ul>li").odd();
    ---------------------------------------------------------------------------------------------------------
    1.:first:最开头那一个                                              $("ul>li:first").html()
    2.:last:最后那一个                                                 $("ul>li:last").html()
    3.:eq(index):第index个                                             $("ul>li:eq(2)").html()
    4.:even:偶数(4个字母)                                            $("ul>li:even").length
    5.:odd:奇数(3个字母)                                             $("ul>li:odd").length
    6.:gt(index):>index的全部元素                                      $("ul>li:gt(2)").length
    7.:lt(index):<index的全部元素                                      $("ul>li:lt(2)").length
    8.:not(选择器):除了...以外                                         $("ul>li:not( ul>li:lt(2) )").length
    9.:header:选中所有的标题元素,包括h1、h2...h6                       $(":header").css("background-color", "gray")
    10.:focus:获取当前焦点的元素                                       $("input:focus").css("background-color", "red")
    ---------------------------------------------------------------------------------------------------------
    细节:DOM与jQuery对象的互相转换                                     $($("ul>li:odd")[0]).html()
    细节:DOM与jQuery对象的互相转换                                     $($("ul>li:odd").get(0)).html()

05.可见性选择器
    1.:visible:选中所有可见的元素                                      $(":visible").length
    2.:hidden:选中所有隐藏的元素                                       $(":hidden").length

1.4 事件

01.鼠标事件
    鼠标事件click():单击
    鼠标事件mouseover():悬浮
    鼠标事件mouseout():离开
    鼠标事件mouseover + mouseout:链式写法
    ---------------------------------------------------------------------------------------------------------
    $(document).ready(function(){
        $("h1").click(function(){
            alert("单击事件...");
        });
        $("div").mouseover(function(){
            alert("悬浮事件...");
        });
        $("div").mouseout(function(){
            alert("离开事件...");
        });
        $("div").mouseover(function(){
            alert("悬浮事件...");
        }).mouseout(function(){
            alert("离开事件...");
        });
    });

02.键盘事件
    键盘事件keydown():键盘按键 从上往下的 过程
    键盘事件keypress():按键被压到 最底部
    键盘事件keyup():松开按键
    ---------------------------------------------------------------------------------------------------------
    $(document).ready(function(){
        $("body").keydown(function(){
            if(event.keyCode == 13){
                alert("按键 从上往下的 过程...回车");
            }
        });
        $("body").keypress(function(){
            alert("按键被压到最底部...");
        });
        $("body").keyup(function(){
            alert("松开按键");
        });
    });

03.表单事件
    表单事件focus:获取光标
    表单事件blur:失去光标
    ---------------------------------------------------------------------------------------------------------
    //二、jquery事件:无onXXX,例如click()  写在ready()内
    $(document).ready(function(){
        $("#uid").focus(function(){
            $(this).css("background-color", "red");
        });
        $("#uid").blur(function(){
            $(this).css("background-color", "green");
        });
    });

04.绑定事件、移除事件
    bind 绑定事件
    unbind 移除事件
    ---------------------------------------------------------------------------------------------------------
    $(document).ready(function(){
        $("#uid").bind("click",function(){
            alert("bind形式的单击事件...");
        });
        $("body").bind( {"keydown":function(){                  //绑定多个事件
                alert("按键 从上到下的过程...");
            },"keypress":function(){
                alert("按键 被压到最底部...");
            }
        } );
    });

05.复合事件、显示效果
    hover(f1,f2):切换使用mouseover()和mouseout()
    toggle(f1,f2,f3,...,fn):轮回使用多个click()事件,toggle()还有其他含义(隐藏与显示)
    ---------------------------------------------------------------------------------------------------------
    $(document).ready(function(){
        $("h2").hover(function(){
            alert("悬浮...");
        }, function(){
            alert("离开...")
        });
        $("body").toggle(function(){
            $(this).css("background-color", "red");
        },function(){
            $(this).css("background-color", "yellow");
        },function(){
            $(this).css("background-color", "blue");
        });
    });

1.5 操作DOM

01.样式操作
    1.设置CSS:jquery对象.css("属性名","属性值");
               jquery对象.css({ "属性名":"属性值", "属性名":"属性值", ... ,"属性名":"属性值" });
    2.追加或移除样式class:addClass("x"):增加某一个
                          addClass("x x x"):增加多个,空格隔开
                          removeClass("x"):移除某一个
                          removeClass("x x x"):移除多个,空格隔开
                          removeClass():移除全部样式
                          toggleClass("x x x"):切换追加与移除
    ---------------------------------------------------------------------------------------------------------
    $(document).ready(function(){
        $("#color").css("color","red");
        $("#color").css({"color":"red",
                        "font-size":"100px",
                        "background-color":"gray"});

        $("#test").addClass("myStyle1");
        $("#test").addClass("myStyle1 myStyle2 myStyle3");
        $("#test").click(function(){
            $("#test").removeClass("myStyle1");
            $("#test").removeClass("myStyle1 myStyle2 myStyle3");
            $("#test").removeClass();
            $("#test").toggleClass("myStyle1 myStyle2 myStyle3");
        });
    });

02.内容操作
    1.html():获取值,获取的是元素的内容 ,包含了 元素内部的 各种标签
    2.text():获取值,只获取文本值
    3.val():获取value值
    ---------------------------------------------------------------------------------------------------------
    $(document).ready(function(){
        alert($("#test").html());
        alert($("#test").text());
        alert($("#uid").val());
    });

03.节点与属性操作
    a.节点操作
        1.查询节点:jQuery选择器
        2.创建节点:$()
                   $(选择器):获取节点
                   $(DOM对象):DOM对象转换为jQuery对象
                   $(html字符串):$("<li onclick="..">xxx</li>")
        3.插入节点
            a.内部插入
                function myTest1(){
                    var $myElement = $("<li>xxx</li>");                         //创建节点

                    $("ul").append($myElement);                                 //1.$(A).append(B)       将B插入到A之后,如:$("ul").append($node);
                    $myElement.appendTo($("ul"));                               //  $(A).appendTo(B)     将A插入到B之后,如:$node.appendTo("ul");

                    $("ul").prepend($myElement);                                //2.$(A).prepend(B)      将B插入至A之前,如:$("ul").prepend($node);
                    $myElement.prependTo($("ul"));                              //  $(A).prependTo(B)    将A插入到B之前,如:$node.prependTo("ul");
                }
            b.外部插入
                function myTest2(){
                    var $myElement = $("<p>yyy</p>");                           //创建节点

                    $("ul").after($myElement);                                  //1.$(A).after(B))       将B插入到A之后,如:$("ul").after($node);
                    $myElement.insertAfter($("ul"));                            //  $(A).insertAfter(B)  将A插入到B之后,如:$node.insertAfter("ul");

                    $("ul").before($myElement);                                 //2.$(A).before(B)       将B插入至A之前,如:$("ul").before($node);
                    $myElement.insertBefore($("ul"));                           //  $(A).insertBefore(B) 将A插入到B之前,如:$node.insertBefore("ul");
                }
            4.替换节点
                function myTest3(){
                    $("ul>li:eq(1)").replaceWith("<li>xx</li>");                //1.$X.replaceWith(Y)    用Y替换X

                    $("<li>xx</li>").replaceAll("ul>li:eq(1)");                 //2.$X.replaceWith(Y)    用X替换Y
                }
            5.删除节点
                function myTest4(){
                    $("ul>li:eq(1)").remove();                                  //1.remove():彻底删除

                    $("ul>li:eq(2)").detach();                                  //2.detach():将结点删除,但关联的事件、数据不会删除(不推荐使用)

                    $("ul>li:eq(3)").empty();                                   //3.empty():只删除内容
                }
            6.克隆节点
                function myTest5(){
                    var $clo = $("ul>li:eq(1)").clone();                        //1.clone(true|false):克隆节点,(如果为true,则克隆节点关联的事件; 反之为false,则不会*/
                    $("ul").append($clo);                                       //  验证克隆是否成功:将克隆后的节点内部插入到ul列表
                }
    b.属性操作
        function myTest6(){
            alert( $("#uid").attr("value") );                           //1.attr("属性名"):获取属性值value
            alert( $("#uid").attr("type") );                            //  attr("属性名"):获取属性值type

            $("#uid").attr("name", "zs");                               //2.attr("属性名","属性值"):设置属性值
            alert( $("#uid").attr("name") );                            //  验证是否修改属性值成功

            $("#uid").attr({"name":"ls", "value":"1111"});              //3.attr({ "属性名":"属性值", "属性名":"属性值", "属性名":"属性值" } );
            alert( $("#uid").attr("name") + "---" +                     //  验证是否修改属性值成功
                   $("#uid").attr("value") );

            $("#uid").removeAttr("value");                              //removeAttr("属性名"):删除属性值
            alert( $("#uid").attr("value") );                           //  验证是否删除属性值成功
        }

04.获取集合与遍历集合
    a.获取集合
        function myTest1(){
            var $list1 = $("ul");                                       //1.集合                          $(...)
            alert($list1.length);

            var $list2 = $("ul").children("li");                        //2.子节点集合                       $(...).children("li")
            alert($list2.length);

            var $list3 = $("body").find("li");                          //3.后代集合(不推荐使用,影响性能)    $(...).find( "li")
            alert($list3.length);

            var $list4 = $("ul>li:eq(1)").next();                       //4.同辈集合:                       next():后一个
            alert($list4.html());

            var $list5 = $("ul>li:eq(1)").prev();                       //4.同辈集合:                       prev():前一个
            alert($list5.html());

            var $list6 = $("ul>li:eq(1)").siblings();                   //4.同辈集合:                       siblings():真正的同辈  前、后
            alert($list6.length);

            var $list7 = $("ul>li:eq(1)").parent();                     //5.前辈集合:                       parent():父代集合
            alert($list7.html());

            var $list8 = $("ul>li:eq(1)").parents("ul");                //5.前辈集合:                       parents("ul"):祖先集合  中 只选择"ul"
            alert($list8.html());

            var $list9 = $("ul>li:eq(1)").siblings(":odd");             //6.过滤集合                        i.很多方法的()就是一个过滤选择器,例如parents("ul")、children("li")...
            $list9.css("background-color","pink");                      //                                  ii.filter("选择器...");
        }
    b.遍历集合
        function myTest2(){
            $("ul>li").each(function(){                                 //1.each()
                alert($(this).html());
            });

            $("ul>li").each(function(index){                            //2.each(index):index代表当前是第X个
                alert(index + "," + $(this).html());
            });

            $("ul>li").each(function(index,element){                    //3.each(index, element):element代表当前元素,注意一点,element是DOM对象,需要使用$()转化为jQuery对象
                alert(index + "," + $(element).html());
            });
        }

05.CSS-DOM操作
    $(document).ready(function(){
        $("#test").height(500);                                         //1.height(500):设置高度500
        alert( $("#test").height() );                                   //  height(   ):获取高度

        $("#test").width(500);                                          //2.width(500):设置宽度500
        alert( $("#test").width() );                                    //  width(   ):获取宽度

        $("#test").offset(function(index,oldOffset){                    //3.offset(index,oldOffset):设置偏移量,index代表第几个偏移量,oldOffset代表当前坐标
            var newOffset = new Object();                               //  newOffset代表新坐标
            newOffset.left = oldOffset.left + 10;
            newOffset.top = oldOffset.top  + 10;
            return newOffset;
        });
        var $myOffset = $("#test").offset();                            //  offset():获取偏移量,相对于"左上角的点",有两个坐标(left、top)
        alert( $myOffset.left + "," + $myOffset.top)

        $("#uid").click(function(){                                     //4.offsetParent():获取(已定位)的最近的祖先元素
            $(this).offsetParent().css("border","10px solid blue");     //   已定位:元素position属性(默认static)被设置为了relative / absolute / fixed
        });

        $("#test").scrollLeft(30);                                      //5.scrollLeft(30):设置30偏移量,相对滚动条左侧的偏移量
        alert( $("#test").scrollLeft() );                               //  scrollLeft(  ):获取偏移量,相对滚动条左侧的偏移量$("#test").scrollLeft(30);

        $("#test").scrollTop(30);                                       //6.scrollTop(30):设置30偏移量,相对滚动条顶部的偏移量
        alert( $("#test").scrollTop() );                                //  scrollTop(  ):获取偏移量,相对滚动条顶部的偏移量
    });

1.6 表单校验

01.字符串处理
    <html>
    <head>
        <title>表单校验</title>
        <!-- 引入jQuery-->
        <script type="text/javascript" src="js/jquery-3.3.1.js" ></script>

        <!--使用引入jQuery-->
        <script type="text/javascript">

            //jQuery方式
            $(document).ready(function(){
                /*
                    blur():失去焦点时触发
                */
                $("#uage").blur(function(){
                    var $age = $("#uage").val();
                    if(!($age>0 && $age<100)){
                        alert("年龄输入有误!");
                    }
                });

                /*
                    submit():当单击submit按钮触发时,通过返回值true|false告知程序是否校验成功!
                */
                $("myFrom").submit(function(){
                    var $name = $("#uname").val();
                    var $pwd = $("#upwd").val();
                    var $height = $("#uheight").val();
                    if($name.length<2 || $name.length>6){
                        alert("名字必须填写2-6位!");
                        return false;//校验失败
                    }
                    if($pwd.length<=6){
                        alert("密码必须填写6位以上!");
                        return false;//校验失败
                    }
                    if($height<100 || $height>200){
                        alert("身高应该在100-200!");
                        return false;//校验失败
                    }
                    return true;//校验成功,表单提交
                });
            });


            //JavaScript方式
            /*
                onsubmit():当单击submit按钮触发时,通过返回值true|false告知程序是否校验成功!
            */
            function check(){
                var $name = $("#uname").val();
                var $pwd = $("#upwd").val();
                var $height = $("#uheight").val();
                if($name.length<2 || $name.length>6){
                    alert("名字必须填写2-6位!");
                    return false;//校验失败
                }
                if($pwd.length<=6){
                    alert("密码必须填写6位以上!");
                    return false;//校验失败
                }
                if($height<100 || $height>200){
                    alert("身高应该在100-200!");
                    return false;//校验失败
                }
                return true;//校验成功,表单提交
            }

        </script>
    </head>
        <body>
            <form id="myFrom" action="03050100_表单校验_result.html" onsubmit="return check()">
                姓名:<input id="uname"/><br/>
                密码:<input id="upwd" type="password"/><br/>
                身高:<input id="uheight"/><br/>
                <input type="submit" value="注册">
            </form>
        </body>
    </html>

02.正则表达式
    <html>
    <head>
        <title>表单校验</title>
        <!-- 引入jQuery-->
        <script type="text/javascript" src="js/jquery-3.3.1.js" ></script>

        <!--使用引入jQuery-->
        <script type="text/javascript">

            //jQuery方式
            $(document).ready(function(){
                $("#utel").blur(function(){
                    var $tel = $(this).val();
                    var reg  = /^1\d{10}$/ ;
                    if(!(reg.test($tel))){//如果校验失败!
                        if($tel="" || $tel.length==0){//失败原因一:空/长度为0,则不显示隐藏域
                            $("#telTip").css("display","none");
                        }else{//失败原因二:不符合正则表达式的规则,则显示隐藏域
                            $("#telTip").css("display","inline");
                        }
                    }else{//如果校验成功!
                        $("#telTip").css("display","none");
                    }
                });

                $("#uemail").blur(function(){
                    var $email = $(this).val();
                    var reg  = /^\w+@[0-9a-zA-Z]{2,4}\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2,3})?$/ ;
                    if( !reg.test($email)){//如果校验失败!
                        if($email="" || $email.length==0){//失败原因一:空/长度为0,则不显示隐藏域
                            $("#emailTip").css("display","none");
                        }
                        else{//失败原因二:不符合正则表达式的规则,则显示隐藏域
                            $("#emailTip").css("display","inline");
                        }
                    }else{//如果校验成功!
                        $("#emailTip").css("display","none");
                    }
                });
            });
        </script>
    </head>
        <body>
            <form id="myFrom" action="03050100_表单校验_result.html" onsubmit="return check()">
                姓名:<input id="uname"/><br/>
                密码:<input id="upwd" type="password"/><br/>
                身高:<input id="uheight"/><br/>
                电话:<input id="utel"/><font id="telTip" color="red" style="display:none">电话号码格式不正确</font><br/>       <!--style="display:none设置隐藏域:将文本进行隐藏-->
                邮箱:<input id="uemail"/><font id="emailTip"color="red" style="display:none">邮箱格式不正确</font><br/>      <!--style="display:none设置隐藏域:将文本进行隐藏-->
                <input type="submit" value="注册">
            </form>
        </body>
    </html>

03.表单选择器
    <html>
    <head>
        <title>表单校验</title>
        <!-- 引入jQuery-->
        <script type="text/javascript" src="js/jquery-3.3.1.js" ></script>

        <!--使用引入jQuery-->
        <script type="text/javascript">

            //jQuery方式
            $(document).ready(function(){
                //情况一:选择标签input,实际上可以拿到多个标签,包括input、textarea、select、button,可以遍历证明!
                $(":input").each(function(){
                    alert($(this).attr("name"));
                });

                //情况二:除input的其他标签,仅代表自己一个,直接使用即可
                $(":input").attr("myFile");
            });
        </script>
    </head>
        <body>
            <!--情况一:选择标签input,实际上可以拿到多个标签,包括input、textarea、select、button,可以遍历证明!-->
            <input type="text"   name="myText" /><br/>
            <input type="button" name="myButton"/><br/>
            <textarea            name="myTextArea"></textarea><br/>

            <!--情况二:除input的其他标签,仅代表自己一个,直接使用即可-->
            <input type="file"   name="myFile"/><br/>
        </body>
    </html>

2 javascript

2.1 basic

01.bio1
    1.JS可以通过不同的方式来输出数据、与用户交互的函数:alert,prompt 和confirm、JS关键字、现代模式,"use strict"、ES6 模块加载
    2.JS语法、var、let、const
    3.运算符、值的比较、空值合并运算符 '??'、运算符的扩展(ES6)
    4.数据类型、类型转换、Symbol
    5.条件语句
    6.循环语句
    7.错误处理

02.bio2
    1.Proxy、Reflect
    2.Proxy对象
    3.Reflect对象
    4.Eval 执行代码字符串
    5.BigInt
    6.ArrayBuffer

03.bio3
    es6 ~ es14

01.style1
    1.块级作用域
    2.字符串
    3.解构赋值
    4.对象
    5.数组
    6.函数
    7.Map 结构
    8.Class
    9.模块
    10.ESLint 的使用

02.style2
    1.概述
    2.术语
    3.抽象操作的标准流程
    4.相等运算符
    5.数组的空位
    6.数组的 map 方法

2.2 colls

01.bio
    1.原始类型的方法(字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined))
    2.数字类型
    3.字符串
    4.数组
    5.Iterable object(可迭代对象)
    6.Map映射、Set集合
    7.WeakMap and WeakSet(弱映射和弱集合)
    8.Object.keys,values,entries
    9.解构赋值
    10.JSON方法
    ---------------------------------------------------------------------------------------------------------
    遍历容器:
    1.遍历字符串
    2.遍历数组
    3.遍历可迭代对象
    4.遍历Map映射
    5.遍历Set集合
    6.遍历Object的keys、values、entries
    ---------------------------------------------------------------------------------------------------------
    Iterator 和 for...of 循环(ES6):
    1.Iterator(遍历器)的概念
    2.默认 Iterator 接口
    3.调用 Iterator 接口的场合
    4.字符串的 Iterator 接口
    5.Iterator 接口与 Generator 函数
    6.遍历器对象的 return(),throw()
    7.for...of 循环

02.object
    1.对象基础
    2.对象方法,"this"
    3.symbol类型
    4.对象引用和复制
    5.构造器和操作符 "new"
    6.原始值转换
    7.垃圾回收
    8.可选链 "?."
    9.属性标志和属性描述符
    10.属性的 getter 和 setter
    11.对象的扩展(ES6)
    12.对象的新增方法(ES6)

03.standard
    1.Object对象
    2.Array对象
    3.包装对象
    4.Boolean对象
    5.Number对象
    6.String对象
    7.Math对象
    8.Date对象
    9.RegExp对象
    10.JSON对象

2.3 dram

01.class
    1.类语法
    2.类继承
    3.静态属性和静态方法
    4.私有的和受保护的属性和方法
    5.扩展内建类
    6.类检查
    7.Mixin模式
    8.装饰器(ES6)
    9.类的基本语法(ES6)
    10.类的继承(ES6)

02.function
    1.函数定义
    2.函数参数
    3.函数调用
    4.闭包示例函数
    5.this使用场景
    6.递归和堆栈
    7.全局对象
    8.老旧的var、var 与 let/const 有两个主要的区别
    9.计划调用:setTimeout、setInterval
    10.函数的扩展(ES6)

03.module
    1.模块简介
    2.导出与导入
    3.动态导入
    4.Module 的语法
    5.Module 的加载实现

04.prototype
    1.原型继承
    2.原生的原型
    3.F.prototype
    4.原型方法,没有 __proto__ 的对象

2.4 sync

01.async
    async 函数:
    1.含义
    2.基本用法
    3.语法
    4.async 函数的实现原理
    5.与其他异步处理方法的比较
    6.实例:按顺序完成异步操作
    7.顶层 await
    ---------------------------------------------------------------------------------------------------------
    异步遍历器:
    1.同步遍历器的问题
    2.异步遍历的接口
    3.for await...of
    4.异步 Generator 函数
    5.yield* 语句

02.generator
    Generator 函数的语法:
    1.简介
    2.next 方法的参数
    3.for...of 循环
    4.Generator.prototype.throw()
    5.Generator.prototype.return()
    6.next()、throw()、return() 的共同点
    7.yield* 表达式
    8.作为对象属性的 Generator 函数
    9.Generator 函数的this
    10.含义
    11.应用
    ---------------------------------------------------------------------------------------------------------
    Generator 函数的异步应用:
    1.传统方法
    2.基本概念
    3.Generator 函数
    4.Thunk 函数
    5.co 模块

03.promise,async/await
    1.回调简介
    2.Promise 对象的构造器(constructor)语法
    3.Promise 链
    4.使用 promise 进行错误处理
    5.Promise 类有 6 种静态方法
    6.Promisification
    7.微任务(Microtask)
    8.async/await
    9.Promise对象(ES6)

2.5 zero

01.dom
    1.概述
    2.Node 接口
    3.NodeList 接口,HTMLCollection 接口
    4.ParentNode 接口,ChildNode 接口
    5.Document 节点
    6.Element 节点
    7.属性的操作
    8.Text 节点和 DocumentFragment 节点
    9.CSS 操作
    10.Mutation Observer API

02.event
    1.EventTarget 接口
    2.事件模型
    3.Event 对象
    4.鼠标事件
    5.键盘事件
    6.进度事件
    7.表单事件
    8.触摸事件
    9.拖拉事件
    10.其他常见事件
    11.GlobalEventHandlers 接口

03.form
    表单,控件:
    1.表单属性和方法
    2.聚焦:focus/blur
    3.事件:change,input,cut,copy,paste
    4.表单:事件和方法提交

04.model
    Browser对象:
    1.Window对象
    2.Navigator对象
    3.Screen对象
    4.History对象
    5.Location对象
    6.存储对象:localStorage 和 sessionStorage
    ---------------------------------------------------------------------------------------------------------
    在浏览器中存储数据:
    1.Cookie,document.cookie
    2.Web 存储对象 localStorage 和 sessionStorage
    3.IndexedDB 是一个浏览器内建的数据库,它比 localStorage 强大得多
    ---------------------------------------------------------------------------------------------------------
    CORS 通信:
    1.两种请求
    2.简单请求:基本流程、withCredentials 属性
    3.非简单请求:预检请求、预检请求的回应、浏览器的正常请求和回应
    4.与 JSONP 的比较
    ---------------------------------------------------------------------------------------------------------
    File 对象,FileList 对象,FileReader 对象:
    1.File 对象
      构造函数
      实例属性和实例方法
    2.FileList 对象
    3.FileReader 对象
    ---------------------------------------------------------------------------------------------------------
    表单,FormData 对象:
    1.表单概述
    2.FormData 对象
      概述
      实例方法
    3.表单的内置验证
      自动校验
      checkValidity()
      willValidate 属性
      validationMessage 属性
      setCustomValidity()
      validity 属性
      表单的 novalidate 属性
    4.enctype 属性
    5.文件上传
    ---------------------------------------------------------------------------------------------------------
    Location 对象,URL 对象,URLSearchParams 对象:
    1.Location 对象
    2.URL 的编码和解码
    3.URL 接口
    4.URLSearchParams 对象
    ---------------------------------------------------------------------------------------------------------
    XMLHttpRequest对象:
    1.简介
    2.XMLHttpRequest 的实例属性
    3.XMLHttpRequest 的实例方法
    4.XMLHttpRequest 实例的事件
    5.Navigator.sendBeacon()

3 typescript

3.1 basic

01.数据类型:
    0.变量声明、类型检查
    1.原始数据类型:1.布尔值 2.数字 3.字符串 4.空值(Void) 5.Null 和 Undefined;其他数据类型:数组、元组、枚举、Any、Void、Never、Object
    2.任意值(Any)用来表示允许赋值为任意类型
    3.类型推论、类型断言、类型别名
    4.联合类型:联合类型(Union Types)表示取值可以为多种类型中的一种
    5.对象的类型——接口:使用接口(Interfaces)来定义对象的类型
    6.数组的类型:数组类型有多种定义方式,比较灵活
    7.函数的类型:函数是 JavaScript 中的一等公民
    8.Symbols:symbol类型的值是通过Symbol构造函数创建的,Symbols是不可改变且唯一的,像字符串一样,symbols也可以被用做对象属性的键
    9.高级类型:交叉类型、联合类型、类型保护、可选参数、类型别名、字符串字面量类型、多态的 this 类型和索引类型
    10.类型兼容性
    11.迭代器和生成器

02.遍历容器:
    1.遍历字符串
    2.遍历数组
    3.遍历可迭代对象
    4.遍历元组
    5.遍历Map映射
    6.遍历Set集合
    7.遍历Object的keys、values、entries

3.2 dram

01.示例
    1.接口
    2.类
    3.函数
    4.泛型
    5.装饰器
    6.Mixins

3.3 module

01.示例
    1.内置对象
    2.声明文件
    3.模块
    4.命名空间
    5.命名空间和模块
    6.模块解析
    7.声明合并
    8.JSX
    9.三斜线指令

4 常见问题

4.1 倒计时:3种

01.setInterval
    function example1(leftTime) {
        let t = leftTime;
        setInterval(() => {
            t = t - 1000;
            console.log(t);
        }, 1000);
    }
    example1(10);

02.setTimeout
    function example2(leftTime) {
        let t = leftTime;
        setTimeout(() => {
            t = t - 1000;
            if (t > 0) {
                console.log(t);
                example2(t);
            }
            console.log(t);
        }, 1000);
    }

03.requestAnimationFrame
    function example4(leftTime) {
        let t = leftTime;
        function start() {
            requestAnimationFrame(() => {
                t = t - 1000;
                setTimeout(() => {
                    console.log(t);
                    start();
                }, 1000);
            });
        }
        start();
    }

4.2 线程池:webWorker

00.Web Worker线程池概述
    a.定义
        Web Worker线程池是一种在Web应用中管理多个Web Worker线程的机制。
        @它允许开发者在浏览器中并行执行JavaScript代码,从而提高应用的性能和响应速度。
    b.用途
        提高计算密集型任务的执行效率
        避免阻塞主线程,保持UI的流畅性
        管理和复用多个Web Worker,减少资源消耗

01.Web Worker基础
    a.创建Web Worker
        使用JavaScript创建一个新的Web Worker。
        // worker.js
        self.onmessage = function(event) {
            const result = event.data * 2; // 示例计算
            self.postMessage(result);
        };

        // main.js
        const worker = new Worker('worker.js');
        worker.onmessage = function(event) {
            console.log('Result from worker:', event.data);
        };
        worker.postMessage(10);
    b.通信机制
        主线程和Web Worker之间通过`postMessage`和`onmessage`进行通信。

02.实现线程池
    a.线程池设计
        线程池通过预先创建一定数量的Web Worker来管理任务的分配和执行。
    b.示例实现
        class WorkerPool {
            constructor(size) {
                this.size = size;
                this.pool = [];
                this.tasks = [];
                this.init();
            }

            init() {
                for (let i = 0; i < this.size; i++) {
                    const worker = new Worker('worker.js');
                    worker.onmessage = (event) => {
                        const { resolve } = this.tasks.shift();
                        resolve(event.data);
                        this.runNext();
                    };
                    this.pool.push(worker);
                }
            }

            runTask(task) {
                return new Promise((resolve) => {
                    this.tasks.push({ task, resolve });
                    this.runNext();
                });
            }

            runNext() {
                if (this.tasks.length === 0) return;
                const availableWorker = this.pool.find(worker => worker.idle);
                if (availableWorker) {
                    const { task } = this.tasks[0];
                    availableWorker.idle = false;
                    availableWorker.postMessage(task);
                }
            }
        }

        // 使用线程池
        const pool = new WorkerPool(4);
        pool.runTask(10).then(result => console.log('Task result:', result));
    c.任务调度
        线程池负责调度任务到空闲的Web Worker,并在任务完成后处理结果。

03.优化和注意事项
    a.线程数量
        根据设备性能和任务复杂度合理设置线程池的大小,避免过多线程导致资源竞争。
    b.任务拆分
        将大任务拆分为小任务,以便更好地利用线程池的并行能力。
    c.错误处理
        在Web Worker中添加错误处理机制,确保任务失败时不会影响整个应用。
        -----------------------------------------------------------------------------------------------------
        // worker.js
        self.onerror = function(error) {
            console.error('Worker error:', error);
        };
    d.资源释放
        在不再需要Web Worker时,调用`terminate`方法释放资源。
        worker.terminate();

4.3 刷新页面数据:webSocket、sse

00.总结
    a.WebSocket
        双向通信
    b.Server-Sent Events (SSE)
        单向数据流

01.使用 WebSocket 实现实时数据更新
    a.设置 WebSocket 服务器
        // 安装 ws 库:npm install ws
        const WebSocket = require('ws');

        const wss = new WebSocket.Server({ port: 8080 });

        wss.on('connection', (ws) => {
          console.log('Client connected');

          // 模拟向客户端发送数据
          setInterval(() => {
            const data = JSON.stringify({ message: 'Hello, client!', timestamp: new Date() });
            ws.send(data);
          }, 1000);

          ws.on('close', () => {
            console.log('Client disconnected');
          });
        });
    b.在前端连接 WebSocket 服务器
        // 创建 WebSocket 连接
        const socket = new WebSocket('ws://localhost:8080');

        // 连接成功时的回调函数
        socket.onopen = () => {
          console.log('Connected to WebSocket server');
        };

        // 接收到消息时的回调函数
        socket.onmessage = (event) => {
          const data = JSON.parse(event.data);
          console.log('Received data:', data);

          // 更新页面数据
          document.getElementById('message').innerText = data.message;
          document.getElementById('timestamp').innerText = data.timestamp;
        };

        // 连接关闭时的回调函数
        socket.onclose = () => {
          console.log('Disconnected from WebSocket server');
        };

        // 连接出错时的回调函数
        socket.onerror = (error) => {
          console.error('WebSocket error:', error);
        };
    c.更新页面数据
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>WebSocket Example</title>
        </head>
        <body>
          <h1>WebSocket Example</h1>
          <p>Message: <span id="message"></span></p>
          <p>Timestamp: <span id="timestamp"></span></p>

          <script src="app.js"></script>
        </body>
        </html>

02.使用 Server-Sent Events (SSE) 实现实时数据更新
    a.设置 SSE 服务器
        // 安装 express 库:npm install express
        const express = require('express');
        const app = express();
        const port = 8080;

        app.get('/events', (req, res) => {
          res.setHeader('Content-Type', 'text/event-stream');
          res.setHeader('Cache-Control', 'no-cache');
          res.setHeader('Connection', 'keep-alive');

          // 模拟向客户端发送数据
          setInterval(() => {
            const data = JSON.stringify({ message: 'Hello, client!', timestamp: new Date() });
            res.write(`data: ${data}\n\n`);
          }, 1000);
        });

        app.listen(port, () => {
          console.log(`SSE server running at http://localhost:${port}`);
        });
    b.在前端连接 SSE 服务器
        // 创建 EventSource 连接
        const eventSource = new EventSource('http://localhost:8080/events');

        // 接收到消息时的回调函数
        eventSource.onmessage = (event) => {
          const data = JSON.parse(event.data);
          console.log('Received data:', data);

          // 更新页面数据
          document.getElementById('message').innerText = data.message;
          document.getElementById('timestamp').innerText = data.timestamp;
        };

        // 连接出错时的回调函数
        eventSource.onerror = (error) => {
          console.error('SSE error:', error);
        };
    c.更新页面数据
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>SSE Example</title>
        </head>
        <body>
          <h1>SSE Example</h1>
          <p>Message: <span id="message"></span></p>
          <p>Timestamp: <span id="timestamp"></span></p>

          <script src="app.js"></script>
        </body>
        </html>

4.4 表单提交:不出现跨域

01.回答
    因为Post请求,Content-Type支持multipart/form-data

02.原因
    a.同源策略
        浏览器的同源策略主要限制的是通过JavaScript进行的跨域请求,比如使用XMLHttpRequest或Fetch API
        然而,HTML表单提交(通过<form>元素)并不受同源策略的限制,因为它是浏览器原生支持的行为
    b.表单提交机制
        当用户提交表单时,浏览器会直接向表单的action属性指定的URL发送请求
        这种请求是由浏览器自身发起的,而不是通过JavaScript,因此不受同源策略的限制
    c.Content-Type
        表单提交的Content-Type可以是application/x-www-form-urlencoded、multipart/form-data或text/plain
        其中,multipart/form-data通常用于上传文件
        虽然Content-Type不同,但这并不是避免跨域问题的原因
    d.CORS(跨域资源共享)
        对于通过JavaScript发起的跨域请求,服务器需要设置CORS头来允许跨域访问
        然而,表单提交不需要CORS,因为它不受同源策略的限制