kaixin
Published on 2023-03-18 / 17 Visits
0

jQuery

jQuery导入

远程导入
<script src="网络地址">
本地导入
<script src="文件地址">

jQuery与dom的关系

jQuery的语法
1.$(id class).方法()
$(id class) 查找标签 相当于实例化一个对象
​
2.jQuery("id class 标签名").方法
​
例如:
将标签的文本变换颜色
jQuery(".c1 ").css("color","red")
$(".c1 ").css("color","red")
​
<div>123</div>
​
dom与jq对象的转换
dom对象:
找到标签ele就是一个dom对象
ele = document.querySelector(".c1")
​
jq对象:
$(".c1") 这就是一个jq对象
jq对象 是一个集合数组对象内部放着dom的元素[dom1,dom2....]
​
jq对象转换为dom对象
$(".c1")[0]  因为是一个集合数组 取元素,每一个元素就是一个dom  结果:dom1
​
dom转换为js
$(ele)  转换为dom对象 结果 [dom1]  
不论内部有多少个元素,1...100只要在转换后都是dom对象

jQuery的选择器

1.类选择器
$(".c1")
​
2.id选择器
$("#i1")
​
3.标签名选择器
/$("div")
​
4.通配选择器  全部
$("*")
​
5.组合标签,可以选择多个,只要符合条件就可以,里面可以有id,class,标签名()
$("#li,p")
​
6.后代选择器 定位到 标签的孙子
$(".c1 .c2 ul li")
​
7.子代选择器 只确定父级标签下面的子级标签
$(".c2 > ul")
​
8.属性选择器 选择标签内的特有属性
$(".z1z  [href]")
​
9.属性选择器 中的正则内容 后面的选择内容必须要用单引号
$(".z1z [href$='peg']")
​
10表单选择器 选择属性,和属性值
$("[type ='text']")
$(":text") 简写
​
​
​
div class="c1">
    <div class="c2">
        <ul>
            <li>1</li>
        </ul>
    </div>
</div>
</div>
<input type="text">
<input type="password">
</body>
​
<div class="z1z" >
    <a href="1.peg">1</a>
    <a href="">2</a>
    <a href="">3</a>
</div>

jQuery的筛选器

准却的找到多个标签的其中一个
在一堆dom对象向中,选中想要变化的dom对象,使用筛选器进行筛选。
这种在内部属于字符串
​
1.找到标签的第一个
$(".c1 li:first")
​
2.找到标签的最后一个
$(".c1 li:last")
​
3.按照索引找到标签
$(".c1 li:eq(2)")
​
4.找到索引大于相应
$(".c1 li:gt(2)")
​
5.找到索引小于相应
$(".c1 li:lt(2)")
​
6.根据索引偶数
$(".c1 li:even")
​
7.根据索引奇数
$(".c1 li:odd")
​
​
8.写法不同,根据变量(推荐)
var index=2  定义变量 在外部就是数字2
$(".c1 li").eq(index)  在找到定义变量相对应的标签
​
<ul class="c1">
    <li class="c2">11</li>
    <li>122</li>
    <li>33</li>
    <li>44</li>
    <li>551</li>
    <li>66</li>
</ul>
​

jQuery的的导航查找

1.查看子代标签
children()不加条件就是将全部的子代标签找出来,加上条件就是指定那个标签
$(".c1").children("p")
$(".c1").children()
​
2.找下一个兄弟标签
$(".c5").next()
​
3.找下一个所有的兄弟
$(".c5").nextAll()
​
4.找上一个兄弟
$(".c5").prev()
​
5.找上一个所有的兄弟
$(".c5").prevAll()
​
6.找范围内的兄弟
$(".c5").prevUntil()
​
7.找除了自己以外的全部兄弟
$(".c5").siblings()
​
8.找标签的父级
$(".c3").parent()
​
9.父级的父级
$(".c3").parent().parent()
​
<div class="c1">
    <div class="c2">
        <div class="c3"></div>
        <p>p1</p>
    </div>
    <p>p2</p>
</div>
<ul class="c4">
    <li>1</li>
    <li class="c5">2</li>
    <li>3</li>
    <li>4</li>
    <li id="i1">5</li>
</ul>

jQuery的绑定事件普通

三中用法
​
​
1.on绑定事件  (动态绑定参数)
on 和off
$(“写入标签的父级”).on("事件名 click",匿名函数(){
    事件代码
​
})
​
取消事件
$().off("事件名")
​
​
2.bind绑定事件
 $(“锁定的标签”).bind("事件名:click" ,function () {
        事件代码
 }
​
取消事件
$().off("事件名")
​
​
​
3.$(“锁定的标签”).click(function(){
        事件函数
        this代表当前绑定事件的标签
        $(this)就是当前标签的 转换为jquery对象
})
​
取消事件
$().off("事件名")
​
​

jQuery的绑定事件其他

1.ready和hover事件
鼠标悬浮和离开的事件,在悬浮时发生,在离开时发生
hover鼠标绑定事件,离开和悬浮的发生的事件
$(".c1").hover(over,out)
两个函数
function over() {console.log("over")}  
function out() {console.log("out")}
​
​
2.ready 加载事件
可以在标签上面先加载执行
$(document).ready(function () {事件})
​
​
<div class="c1" >  </div>

jQuery的操作标签

1.标签操作
获取文本信息
​
$(this).html() 纯文本和处理其他标签
$(this).text()  纯文本
​
修改文本信息
​
$(this).html("修改的文本信息")
$(this).text("修改的文本信息")
​
​
2.value取值
只限于select option,input,textarea标签使用,只能用value
​
获取文本信息
$(this).val()
​
修改文本
$(this).val("新内容")
​
​
3.属性操作
​
获取属性值
$("标签id,class..").attr("属性名")
​
设置属性值
$("标签id,class..").attr("属性名","属性值")
​
获得属性值返回真假
$("标签id,class...").prop("属性名")
​

jQuery的循环

var arr=[11,22,33]

$.each(arr,function(i,j){
	i 是数组索引
	j 是数组的值
})


案例:
$("ul li").each(function () {
//循环函数中的this:代指的是每一次循环中的dom对象
//因为this是dom对象,需要转换为jquery,在将转换为整形parseInt进行对比

if(parseInt($(this).html())>30){
$(this).css("color","red")
        }
        })


<ul>
    <li>30</li>
    <li>20</li>
    <li>50</li>
    <li>100</li>
</ul>

jQuery的css用法

单样式
$("c1").css("color","red")

多样式
$(".c1").css({"color":"red","backgroundColor":"#369"})
 
<div class="c1">adads</div> 

获取内容边框尺寸

1.获取内容的宽高尺寸
$("this").width()
$("this").height()

2.获取内边距padding+内容的宽高尺寸
$("this").innerHeight()
$("this").innerWidth()

3.不加参数 边框+内边距+内容的宽高属性
$("this").outerHeight()
$("this").outerWidth()

加参数是内容+内边距+边框+外边距的全部宽高
$("this").outerHeight(true)
$("this").outerWidth(true)

jQuery的属性操作

添加属性
$(this).addClass("属性名")

删除属性
$(this).removeClass("属性名")

悬浮事件
$("标签名,class,id").mousemove(function () {
//添加属性c3,当悬浮在c1上面字体变为倾斜
     $(this).addClass("属性名")
})

jQuery的节点操作

1.创建节点
var $变量 = $("标签名字")

2.节点赋值
$变量.attr("属性名",'属性值')

3.添加属性
按照父级添加
append 追加给父级追加一个子标签 放到最后一个
appendTo 将子级标签添加到父级标签下 放到第一个
perpend  追加给父级追加一个子标签 放到第一个
perpendTo 将子级标签添加到父级标签下  放到第一个

$("父级标签").append($变量)
$("父级标签").appendTo($变量)

按照兄弟添加

添加到兄弟上面
$("兄弟").before($变量)

添加到兄弟下面
$("兄弟").after($变量)

3.删除节点

删除整个标签
$("选中删除的标签id class ..").remove()

删除标签内的文本
$("选中删除的标签id class ..").empty()

4.替换标签
$("需要替换的标签 id class").replaceWith(新建的新标签)
 
 
5.字符串形式添加标签
$("按照兄弟标签").after("添加的标签")

例如
$("需要添加标签的父级标签").after("<div>123</div>")


6.复制标签
$(this).clone()

jQuery的事件委派

$(" ul").on("click"," li",function () {
       //this触发事件的标签
       console.log($(this).html())
   })
将事件委派给父级,触发事件的标签还是li
事件委派 ,将事件给父级,只要添加标签,就会有事件效果,因为事件委派给了父级,下面所有的子标签都会有效果

<ul>
    <li>123</li>
    <li>234</li>
    <li>345</li>
</ul>

jQuery的css位置

$("").offset([coordinates])  // 获取匹配元素在当前视口的相对偏移。
$("").position()             // 获取匹配元素相对父元素的偏移,position()函数无法用于设置操作。
$("").scrollTop([val])       // 获取匹配元素相对滚动条顶部的偏移。
位置偏移案例
   .c1{
            width: 800px;
            height: 500px;
            margin: 100px auto;
            background-color: #e4393c;
            position: relative;
        }

        .c2{
            width: 200px;
            height: 200px;
            background-color: #333333;
        }
        
<div class="c1">
    <div class="c2"></div>
</div>

//获取位置信息
//offset:相对于窗口的偏移  position:相对于已经定位的父标签的偏移量
var off=$(".c2").offset()  //获得偏移量对象
var pos = $(".c2").position()// 不能定位,只能获取父级的相对位置
console.log("off.top:",off.top)
console.log("off.left:",off.left)

//父相对定位,位置left top 才为0
console.log( "pos.left:",pos.left)
console.log("pos.top:",pos.top)

//设置offset
$(".c2").click(function () {
//只有offset才能传参只能时top和left 才能设置,设置上 和左的位置
$(this).offset({top:100,left:100})
    })
返回顶部案例

	 *{
            margin: 0;
        }
        .c1{
            height: 2000px;
            background-color: #b0b0b0;
        }
        .c2{
            width: 120px;
            height: 50px;
            background-color: #333333;
            color: #e4393c;
            text-align: center;
            line-height: 50px;

            position: fixed;
            bottom: 50px;
            right: 20px;
        }
        /*隐藏内容*/
        .hode{
            display: none;
        }

<div class="c1">
    <h3>文章...</h3>
</div>
<div class="c2">返回顶部</div>


//.scrollTo() 获取的是滚动条 与上面顶部的距离,参数是几就会返回到多少位置
console.log($(window).scrollTop())
$(".c2").click(function () {
$(window).scrollTop(0)
})
//隐藏事件,当滚动条到一定距离,显示返回顶部
//相对偏移量
//获取相对偏移量,判断相对偏离大于多少显示返回顶部,小于多少隐藏顶部
$(window).scroll(function () {
console.log($(this).scrollTop())
var v = $(this).scrollTop()
if (v>100){
$(".c2").removeClass(".hode")
}else {
$(".c2").addClass(".hode")
}
})

jQuery的动画

.c1{
            width: 250px;
            height: 250px;
            background-color: #333333;
            position: absolute;
            top: 240px;
            left: 200px;
}
.hide{
            display: none;
}
<p><button class="c2"> animate</button></p>
<div class="c1"></div>

<p>
<button class="s1">显示</button>
<button class="s2">隐藏</button>
</p>
<p>
<button class="s11">显示</button>
<button class="s22">隐藏</button>
</p>
<p>
<button class="s111">显示</button>
<button class="s222">隐藏</button>
</p>
<p>
<button class="s1111">显示</button>
<button class="s2222">隐藏</button>
</p>


1.显示与隐藏

 //显示
$(".s1").click(function () {
$(".c1").removeClass("hide")
})
    //隐藏
$(".s2").click(function () {
$(".c1").addClass("hide")
})

2.show hide效果显示与隐藏

回调函数,只有当前执行完毕后,回调函数才能触发效果
//显示
$(".s11").click(function () {
       $(".c1").show(1000,function () {
           alert(132132)
       })
    })
//隐藏
$(".s22").click(function () {
       $(".c1").hide(1000,function () {
       		alert(123613)
       })
    })
    
3.滑动动画隐藏效果.

(1000,function ()回调函数
//显示
$(".s111").click(function () {
        $(".c1").slideDown(1000,function () {
            alert(132132)
        })
    })
    
//隐藏
 $(".s222").click(function () {
        $(".c1").slideUp(1000,function () {
        alert(123613)
        })
    })

4.fadeIn与fadeOut 淡入淡出的动画效果

//(1000,function ()回调函数
//显示
  $(".s1111").click(function () {
        $(".c1").fadeIn(1000,function () {
            alert(132132)
        })
   })
//隐藏
     $(".s2222").click(function () {
        $(".c1").fadeOut(1000,function () {
        alert(123613)
        })
    })

5.自定义动画

$("").animate(动画效果,动画完成时间,动画完成事件后的回调函数)

$(".c2").click(function () {
        $(".c1").animate({
            "border-radius":"50%",
                "top":340,
            "left":200
            }
        ,1000,function () {  //回调函数,当上面代码执行完毕后,执行回调函数
            $(".c1").animate({
                "border-radius":"0",
                "top":240,
                "left":240}
             ,1000,function () {
            $(".c2").trigger("click")  //trigger模拟事件,当代码点击了c2对应的按钮

            })
            })
    })

扩展方法 (插件机制)

 和python的类方法一样
 
 //自己制作插件
    jQuery.extend({
        //方法1
        方法名:function (参数) {
                //代码
        }

        //方法2
    })
    //调用方法
    $.方法1
    $.方法2

    jQuery.fn.extend({
        方法名:function() {
            //内部代码
    }
    })
    //调用方法
    $("父类值:子类值").方法名

占位符

例如:
 var name="1223";
    var age = 18;

    

    var s=
    `
    姓名:${name},
    年龄:${age}
    `
    console.log(s)

ES6语法

let和const声明变量

1.let变量声明 不存在变量提升问题
特点:
	1.是一个块级的作用域 类似在类中的实例变量一样,只能在声明内部使用,外部不能使用
	2.不允许在相同作用域内,重复声明同一个变量
1-1.变量提升测试
    console.log(b); // 报错,变量b初始化不存在(不存在变量提升问题)
    let b = 100
    console.log(b)

1-2.变量名重复
    let a = 40
    var a = 5000
    console.log(a) // 报错 提示a变量重出现

1-3. 变量可以被覆盖
    let a = 10 ;
    a = 100
    a = 1000
    console.log(a); //1000


2.const变量声明
声明一个只读的常量。一旦声明,常量的值就不能改变
const一旦声明变量,就必须立即初始化,不能留到以后赋值
const foo; // 报错,不能留着以后复制
特点:
	1.声明后不能修改,块级的作用域
	2.变量不能重复,不能被覆盖

console.log(a); // 保存 初始化a变量不存在
const a = 100

2-1.变量声明后就无法在重新赋值
    const a = 100
    a = 1000  // 无法重新赋值,报错
    虽然无法直接修改a变量,但是如果a变量是个对象的情况下是可以对内部的值进行修改的
    const p = {
     name : '123',
     age : 456,
    }
    p.name = '1xx222'

3.var变量声明
特点:
	1.在启动时,将全部的var声明的变量提升到全局作用域中
	2.声明变量是可以被覆盖,可以重复的

 var a;
 console.log(a);  //提示undefind 说明变量提升全局
 var a = 1000

变量提升

使用var
arr  =  [];
for (var i = 0; i < 10; i++) {
        arr[i] = function () {
            return i
        }
    }
console.log(arr);  // [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ] 10个函数的数组
console.log(arr[5]()); // 获取arr的第5个元素的结果是10


使用let 因为let不会存在变量提升的问题,不会污染全局

arr  =  [];
for (let i = 0; i < 10; i++) {
        arr[i] = function () {
            return i
        }
    }
console.log(arr);  // [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ] 10个函数的数组
console.log(arr[5]()); // 5

模板字符串

<div class="box">

</div>


<script>
    // 追加结构
    const obox = document.querySelector('.box')

    let id = 1, name = 'xxx';

    //使用tab上面的反引号 构造一个htmlstr的一个字符串
    // ${} 进添加值  ${} 相当于 python进行占位符
    let htmlstr = `
    <ul>
        <li>
            <p id="${id}">${name}</p>
        </li>
    </ul>
    `
    obox.innerHTML = htmlstr
</script>

剩余运算符与扩展运算符

1.函数的默认参数
    function bba(a = 10, b = 20) {  // 带默认参数
        return a + b
    }
    console.log(bba(100, 300));  // 传入 传入100 和300值,覆盖原来的带有参数的值

//默认参数可以是一个函数    
    function add(a,b=date(5)){
        return a+b
    }
    function date(val){
        return 5 + val // 必须是有返回值的
    }

2.剩余运算符
    //es6写法  剩余参数 由... 紧跟者一个参数实现的
    // ...key 剩余参数固定写法 参数名可以随便写
    //  ...key剩余参数解决了 arguments(伪数组)的意思 
    function pick(object, ...key) { // ...key 返回一个数组
        console.log(key)  // ...key 接受到 传入'title', 'author', "year"3个名称

        let res = Object.create(null)
        for (let i = 0; i < key.length; i++) {
            res[key[i]] = object[key[i]]
        }
        return res
    }
    // book对象
    let book = {
        title: '1231',
        author: "65465",
        year: 2019,
    }
    //获取pick函数处理的值赋值给bookdata // pick接受了pick
    let bookdata = pick(book, 'title', 'author', "year") 
    console.log(bookdata)
    // 剩余参数:接受函数中剩余的参数 返回一个数组 和python中的*args一样属于位置参数

3.扩展运算符
扩展运算符:将数组进行分割,将改革想作为分离的参数进行传入函数中
const arr = [11,22,33,44,566,778979,9879]
console.log(Math.max(...arr))  // 使用扩展运算符 ...数组  可以将数组进行分离为一个个的元素,进行比较 
    

箭头函数

es6的箭头函数 => 来定义 取代function(){} 等价于 ()=>{} 匿名函数

add = function(a,b){
	return a + b
}

add = (a,b)=>{
	return a + b
}

add = (a,b) => a+b // 默认存在一个return

1.无参数 必须有()存在
()=>{
    return '123456'
}

2.单个参数
val => { return val+5
       }

3.单个参数返回
val => val

4.返回对象参数
let getobj = obj => (
    {name:'666',age:18}
)

闭包:
 //闭包函数 fn 可以表达式进行()起来也可以不用括起来
let fn = (function(){
           return function(){ 
               return 123 
           } 
        })()
fn(); // 需要执行一下

箭头函数闭包
let fns = (() => {
            return () => {
                return 123
            }
        }) (); // 第一层函数执行,获取到的第二层的function函数(没有执行) 需要执行
        fn();

箭头函数指向this问题

es6 解决this指向问题 使用=> 就会找上层的作用域
箭头函数之后没有this指向,通过查找作用域进行找 
一但使用箭头函数,当前有没有作用域,就找上层的作用域
3层作用域    this

let pa = {
    id : 10,
    // 2级作用域 this
    init:function(){  
        // 1级作用域 this
        document.addEventListener('click',(event)=>{
            console.log(this); 
            this.doSomeThings(event.type) 
            // console.log(event.type) 
        },false)
    },
    doSomeThings:function(type){
        console.log(`事件类型${type},事件id${this.id}`)
    }

}
pa.init()
console.log(pa.doSomeThings());

怎么查找作用域
在 document.addEventListener方法定义的内部是一个作用域
这个作用域上层指向了 init:function init变量
init 变量的上层作用域 指向了对象pa 所以 this指向pa对象

假设 int:function  定义为箭头函数 => 那么相当于 init没有作用域,就会找到pa对象的作用域
在找到window 作用域练 最外层.

箭头函数注意:
1.使用箭头函数就会内部就没有 arguments 方法,因为使用箭头函数就没有作用域链,就会指向weindow

 let pa = ()=>{
     console.log(arguments)
     return 10+20
 }
 console.log(pa())

2 箭头函数不能使用new关键字实例化对象
let pa = ()=>{} // 因为箭头函数无法实现作用域
console.log(pa) // ()=>{}  他不是一个对象 语法糖 表达式  function 类型
let p = function(){}
console.log(p()) // ƒ (){} 也是一个对象 function 类型
let p = new pa

解构赋值

let info = {
    type: 'id',
    name: ' askjh'
}
es6 完全结构
let { type, name } = info // 进行了赋值
console.log(type, name)  // id,askjh

//不完全结构 可以忽略某些属性
let obj = {
     a: {
        name: '张三'
     }, // 对象
     b: [], // 数组
     c: 'hello world'

}
let {a} = obj // 获取obj对象一些值
console.log(a) // {name: '张三'}

还可以使用 剩余运算符进行获取
let {a,...bs} = obj
console.log(bs) // {b: Array(0), c: 'hello world'} 获取剩余参数的对象


// 使用默认值
let {a,b=30} = {a:40}
console.log(a,b) // 40 30



// 对于数组的使用
let arr = [1,2,3]
let [a,b,c] = arr
console.log(a,b,c) // 1 2 3 

// 嵌套结构
let [n,[d],e] = [1,[2],3] // 相当于python 中的 a,b = 1,3 但是需要根据对应参数的形式获取值
console.log(n,d,e) //1 2 3

对象的扩展

1. es6 直接写入变量的函数 作为对象的属性
const name = '消息下', age = 12
const pe = {
name,
age,
sayName(){
console.log(name) //  消息下
}
}
pe.sayName() // 执行函数


2. set 方 与 get 方法的使用
// 当直接执行get 方法就会根据默认值执行
// 如果对set方法传入参数,就会现去set方法中进行判断 在执行get方法
let caet = {
    wheel:4 ,
    set(val){ // 取值
        if (val < this.wheel){
            throw new Error('数量太少') // throw 抛出异常
        }
    },
    get(){ // 读值
        return this.wheel
    }
}
caet.set(3) // 对方法传入3时,在执行 get 就会获取set值的判断结果
console.log(caet.get()) // 如果不对set传入值,那么默认就会参数就是wheel

3. 属性表达式
const obj = {}
obj.isshow = true // 对obj对象进行赋值
console.log(obj); // {isshow: true}
const name = 'a'
obj[name+'bc'] = 123 // 将name变量 和 bc 进行拼接进行写入对象中
console.log(obj) // {isshow: true, abc: 123}
obj['f'+ 'cc'] = function(){
    console.log(this);
}
console.log(obj) // {isshow: true, abc: 123, fcc: ƒ}



4.对象方法
// is() 相当于 ===  比较与两个值是否严格相同
console.log(NaN === NaN); //  不严谨 false
console.log(Object.is(NaN,NaN));  // true

5.assign() 对象的合并  // 属于浅拷贝
let t = {

}   
let b = {
    a:10
}
Object.assign(t,b) // 将第二个以后的全部对象,合并到第一个对象中  返回一个新对象
console.log(t) // {a: 10}

symbol类型

原始数据 symbol ,表示他他是一个独一无二的值
const name = Symbol('name') // 内存地址不一样
const name2 = Symbol('name') // 独一无二的一个值
const name3 = "name" 

console.log(name3 ===name)//false 
console.log(name === name2); //false 
console.log(typeof name ) // 类型symbol不是字符串
# 用来定义对象的私有变量,可以设置对象的私有的属性
# 不能使用new命令 因为生成的 Symbol 是一个原始类型的值,不是对象,所以不能使用new命令来调用
# 也不能作为对象进行使用, 可以认为他是一个字符串
let obj = {
    'name' : '123' 
}
let s2 = Symbol(obj)
console.log(s2); // Symbol([object Object])

# Symbol 值不能与其他类型的值进行运算,会报错
let a = Symbol('a')
console.log('bcd' + a); // 报错

#  Symbol 可以作为if中的参数可以作为bool,但是不能转为数值
let a = Symbol() // 没有描述也是true
console.log(Boolean(a)); // true
if(a){
    console.log('123');
}
console.log(Number(sym)); // 报类型错误


内部方法
const sym = Symbol('foo');
1.返回symbol('描述') 描述
console.log(sym.description ); // "foo"

2.可以作为对象的属性名
let obj = {}
obj[sym] = 123456
或者
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

3.可以作为消除魔术字符串
魔术字符串:在程序中多次出现的
const a = {
    'b':'name' //   魔术字符串
}
const a = {
    'b': Symbol() //  代替 因为每次创建 Symbol 都是不一样的
}


4.Symbol.for(),Symbol.keyFor()
s1 = Symbol.for('123') # 如果希望使用同一个Symbol对象就是for方法,他会全局环境中进行搜索,而Symbol不会,如果Symbol.for已经存在就会调用存在的Symbol.for不会重新创建
Symbol.keyFor('s1') # 为了找到Symbol.for登记的值

set集合类型

无序不可以重复的类型
let set = new Set() // Set(0) {size: 0}
console.log(set); //Set(0) {size: 0} 其中 size 表示集合的长度

常用方法:
set.add('name') // 可以使数值 集合 对象 字符串 布尔值
set.delete('name') // 删除
set.has('name')  // 查看当前值是否存在 返回flase true
set.size // 访问集合的长度
set.forEach((key,val)=>{ // 进行对当前集合的数组进行 遍历 无意义
    console.log(key,val);
})

//将set 变为一个数组
let set2 = new Set([1,2,3,4,4,5,66,44]) // 集合将元素中的数组进行重复的剔除
let arr = [...set2] // 使用扩展用算符转换为一个数组 // 将集合展开
console.log(arr);


// 释放当前资源
// set 无法被释放
let arr1 = [ 1,2,3,4]
arr1 = null

 WeakSet() // 弱类型的set对象 可以被释放 

map类型

map类型是键值对的有序列表,键和值的任意类型
无法被释放

// 声明 map
let map = new Map();
// 进行设置值
map.set("name", '张三')  //Map(1) Map(1) {'name' => '张三'}
//循环遍历 key :name val:张三
console.log(map) // Map(0) { size: 0 } 打印的结构

// 获取值
console.log(map.get('name')); // 张三

// 校验值
console.log(map.has('name')) //  true

//删除值
console.log(map.delete('name')) // 删除后 打印的结果也是 bool类型

// 清除值
map.clear()  //清空值

// 因为这个map结构使数任何类型  key val 可以使任意结构
map.set([11, 2, 3, 44, 5, 6,], 'hello') //{Array(6) => "hello"}
console.log(map);
// 设置多元数组
let m = new Map([["a", 1], ["b", 2]])
console.log(m) // {'a' => 1, 'b' => 2}

数组补充

数组的方法 from of
function add(){
    arguments // 当前对象在函数中引用函数的参数
	console.log(arguments); // 返回一个伪数组 好多方法不能使用
	let arr = Array.from(arguments); // 变为真正的数组
}

add(1,2,3,4)


2.使用扩展用算符进行快送转换运算符
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
let lis = document.querySelectorAll('li') // 获取全部的li标签

console.log([...lis]); // 直接转换

3.使用form对元素进行处理
let lis = document.querySelectorAll('li') // 获取全部的li标签
let list = Array.from(lis, (ele) => { return ele.textContent }) // 第二个参数是一个回掉函数处理转换的数组中的元素
 
 let list2 = Array.from(lis, ele =>  ele.textContent )
 
 4.of方法 将一组的值转换为数组 任意的数据类型转换为数组
 console.log(Array.of(3,1,2,4,5,6,7,88,9)); //[3, 1, 2, 4, 5, 6, 7, 88, 9]


5.数据的其他的方法
5-1.copywithin() 方法 了解
// 复制替换将数组中的值进行替换 返回当前的数组
let a = [1, 2, 3, 4, 5, 6].copyWithin(0, 3) // 原结果[1,2,3,4,5,6]
console.log(a); // [4,5,6,4,5,6]
//从第三个元素开始到后面的全部数替换前面的数0-3的元素


5-2.find查找数值 findindex查找数值的元素
//find 方法找出第一个满足条件的 数组元素
[1, 2, -103, 4, 5, -10, 7].find((n) => {
    return n < 0
}) // -103 结果  找出第一个条件的数组成员

//findindex 找出第一个数组成员的下标索引
[1, 2, -103, 4, 5, -10, 7].findindex((n) => {
    return n < 0
})

5-3.includes 返回一个bool值 表示一个数组是否包含这个值
//作为if 判断条件 是否包含这个元素
console.log([1,2,3,4].includes(2)); // true
console.log([1,2,3,4].includes(10)); //false

6.entries方法
keys(对键的遍历) values(对值的遍历) 返回一个遍历起  可以使用for ... of 进行遍历 通过这些方法生成遍历器

6-1.keys 获取索引
let a = [1, 2, 3, 4, "a", 6].keys()
console.log(a); // 获取的结构 就是一个遍历器Array Iterator
//就可以使用for of 进行遍历
for (let index of a) {
    console.log(index)  // 将数组的数据遍历出来(获取的索引) 和python中的for遍历一样 不同的就是需要生产一个遍历器
}

6-2.values 获取元素
let b = [1, 2, 3, 4, "a", 6].values()
for (let index of b) {
    console.log(index) // 获取的是数组的值 于python中的for相似但是有和dict方法相似
}

6-3.entries 获取val 和key
let c = [1, 2, 3, 4, "a", 6].entries()
for (let [key, val] of c) {
    console.log('这是键', key) // 获取索引
    console.log('这是值', val)  // 获取值
}

迭代器interator

// 迭代器 一种新的遍历机制
// 遍历起就是迭代器
const item = ['1',2,55,'asd'] //只能是数组类型



// func 就是一个函数,是可以执行的函数  迭代器
let func = item[Symbol.iterator]() // 获取数组的中的迭代器,返回一个函数 ƒ values() { [native code] }

console.log(func); // Array Iterator {}迭代器 

// 迭代器的next方法
console.log(func.next()) // {value: '1', done: false} 返回的一个对象 value代表时数组中的值 done false 代表是遍历还没有完成 当done为teru时,说明便利完成
console.log(func.next())
console.log(func.next())
console.log(func.next())
console.log(func.next()) // {value: undefined, done: true} done为true 说明为遍历完成 value变为 空


// 迭代器两个核心:
// 1 迭代器是一个接口,能快捷的访问数据  [Symbol.iterator]( 创建迭起,同给迭代器的next的结果
// 2 迭代器遍历数据结构的指针 第一次调用指向了 1  value指向 1 dome为false 以此类推 
// 当done 为true时,遍历结束

生成器

生成器的应用,异步编程,让异步编程同步执行
1.
function* func(){
    // request是一个方法 res 接受第二次nxet res 参数赋值给 let res变量
    let res = yield request('传入的网络地址') // 3.res 不是yield执行的结果返回的值
    // res 是谁:恢复执行传入next(实参)

    }    
const ite = func() // 1.迭代器对象
ite.next() // 2.恢复yield进行执行 // 执行这个生成器函数
function request(url){
    $.ajax({
        url:url,
        method:'get',
        success(res){
            ite.next(res) // 4.恢复执行并且 将res传入给 生成器值的变量res    
        }
    })
} 

2.加载效果
function* en(){
    add() // 执行第一个开始加载提示
    yield del() // 卡在加载提示这里,当加载提示执行
    func()
}
const ite = en() // 生成器对象
console.log(ite);
ite.next() // 执行第一次
function add(){
    console.log('开始加载... 图片');
} 


function func(){
    console.log('隐藏加载提示...显示图片')
}

function del(){
    //  setInterval计时器
    setTimeout(() =>{
        console.log('加载完成,隐藏加载效果')
        // 加载提示执行后执行
        // 执行生成器中的下一次next方法
        ite.next() // 执行第二次
    },5000)

}

生成器generator

作用:
1.generator 函数 可以通过yield关键字 将函数挂起,为了改变执行流程提供了可读性
2.为异步编程(解决异步代码)
区别:
1.function后  函数名前 * 
2 只能在函数内部使用yield表达式 让函数挂起

1.例如:生成器函数
function* func(){
yield 1; // 当使用yield关键字时,就会在这个位置挂起不走,当使用next才会执行
}
// 返回一个遍历器对象, 可以调用next()方法调用
let fn = func() // 返回一个对象给 fn变量 返回遍历器对象
// 使用next()方法 
// 可以.value取值 done 获取状态(false还可以next true不能next)
console.log(fn.next().done); //打印的结果就是 {valse:1 ,done:false}
// 当第一次调用next 就会卡在第一个yield
// generator 函数是分段执行,yield语句是暂停执行,next就是恢复执行

案例
 // 对迭代器的传值
function* add(){
    console.log('hehehe');
    // x 不是 yield 2 的返回 是当前next 调用 恢复调用yield执行传入的实参
    let x = yield "a" // 当使用next时 卡在这个位置
    console.log('hahah',x);
    let y = yield '123'
    console.log('hahahz',y);
    return x+y
}
let fn = add()
// 先打印 log 中的数据  在进行打印yield关键字中的内容,函数进行挂起
// 在进行执行next 时就恢复执行
console.log(fn.next(10)); // {value: 'a', done: false}

// 当进行传值时,这个next的值传给乐 let 中的x
//  hahah 20
console.log(fn.next(20));  // {value: '123', done: false}

// 当进行传值时 next  中的参数传给y值
// 返回值return x+y找到下一个执行的yield 中的 对value进行赋值,因为最后一次执行done: true
// 所以就赋值到最后一个next 的value中
console.log(fn.next(20)); //{value: 40, done: true}



主要作用就是 不具备 interator 接口的对象提供的遍历操作
将不具备 interrator循环的对象 变为可遍历操作
function* func(obj) { // 生成器写法 + yield 挂起
    const propkey = Object.keys(obj) // 传入的对象 返回一个迭代器
    console.log(propkey);
    for (let p of propkey) { // 迭代器就可以进行for of循环
        yield [p, obj[p]] // 构造结构 {name:1223}  // 使用yield关键字函数挂起
    }
}


const obj = {
    name: 133,
    age: 456
}



console.log(obj); // {name: 133, age: 456} 普通的对象

for (let [key, val] of func(obj)) {
    console.log(key, val);
    console.log(`${key}:${val}`)
}

promise

异步编程的解决方案 承诺  因为是一个对象 所以需要new 创建对象
promise 相当于一个容器,放置这未来要执行的事件(异步)的一个结果
各种异步操作都可以使用同样的方式进行处理 axios库就是基于promise


特点:
1. 对象的状态不收外接影响 异步处理的状态: peendig(进行中) resolved(成功) rejected(失败了)
这三个状态 保存在peomise
2.一旦改变,就会在变,任何时候都可以 得到结果 进行中- 成功  进行中-失败 都存储在peomise

案例:
// 创建对象
//1. new Promise(接受一个回调函数) 
//2. rejected,resolve 回掉函数中接受两个参数(失败和成功) 固定写法
let pro = new Promise(function (rejected, resolved) {
    // rejected,resolve 这个参数都是方法
    // 执行异步操作
    let res = {
        code: 200,
        data: {
            name: '成功了'
        },
        error: '失败 了'
    }
    // 伪造异步操作
    setTimeout(() => {
        if (res.code === 200) { // 如果状态为200
            resolved(res.datas) // 就将成功的值传给resolved成功状态 可以pro对象中的then() 获取成功的值
        } else {
            rejected(res.error)
        }
    }, 1000)
})
console.log(pro); // 返回一个promis对象 对象内部存在两个3个状态

创建的promise对象的回调方法
// 成功状态下 请求后端获取的状态吗和参数
//pro.then() 成功的结果 执行异步操作的成功的结果 内部接受一个回调函数
pro.then((val) => { // 接受回调函数
    // val 接受成功的数据
    console.log(val); // 
}, (err) => { // err接受异步请求中请求状态 错误的内容
    console.log(err)
})


封装异步操作
ex 接受时间
封装了promise 方法,变得更为灵活
function time(ex) {
     return new Promise((rejected, resolved) => {
         setTimeout(() => {
             resolved('成功的信息')
         }, ex);
     })
 }
 time(1000).then((val) => {
     console.log(val)
})

promise封装异步函数

pormise 封装一个ajax 异步请求
const getJSON = function(url){
    //在这个方法中封装一个promise对象
    new Promise((reject,resolve)=>{
        // 创建一个请求
        const xhr = new XMLHttpRequest()
        //打开对象
        xhr.open('GET',url)
        // 设置状态 回调函数
        xhr.onreadystatechange = handler
        //约定返回数据类型
        xhr.responseText = 'json'
        //设置请求头
        xhr.setRequestHeader('Accept','application/json')
        //发送
        xhr.send() // get必须写
        // 回调函数
        function handler(){ // 创建回调函数
            // this指向 xhr对象
            console.log(this.readyState) // 获取数组的状态
            if(this.readyState === 4){
                if(this.status === 200){ // 后端请求的状态
                    resolve(this.response) // 获取的请求体返回  
                }else{
                    reject(new Error(this.statusText)) // 讲请求状态的error
                }
            }
        }
    })
}

getJSON('url') // 传入地址
.then((val)=>{
	console.log(val)
},(error)=>{
	console.log(error);
})


//其他pormise中的其他方法
//then() 方法 第一个参数:relove 回掉方法 第二个参数:可选的reject 状态的回调 
// then() 返回了什么:返回的时新的pormise实例对象 还可以.then()  可以采用链式写法
// 可以特殊写发 链式写法
getJSON('url').then(val=>{
    // 返回正确的操作
}).catch(err=>{
    // 返回错误的操作
})

补充

 // resolve() reject() all() race() finally()
//1 resolve() = reject() 可以转换为 promise对象 现有的任何对象转换为
// let p = Promise.resolve('foo') //将字符串foo转为promis对象
// //等价于
// let p = Promise(resolve => {
//    return resolve('foo')
// }) // 直接返回foo

// console.log(p);
// p.then((val) => {
//     console.log(val); // 结构 foo
// })


// all() 并行的执行这个3个异步 // 一起操作 游戏素材 加载
// let p1 =new Promise((resolve,reject)=>{}) 
// let p2 =new Promise((resolve,reject)=>{}) 
// let p3 =new Promise((resolve,reject)=>{})    

// let lst = [p1,p2,p3]
// let p4 = Promise.all(lst) // 传入一个数组
// p4.then((val)=>{
//     // 3个都成功才是成功
// }).catch((err)=>{
//     // 如果一个失败 就全失败
// })

// race() 请求超时的操作 给某个设置超时的时间并且在超时后执行相应的操作
// 请求图片资源
function img(imgs) {
    return new Promise((resolve, reject) => {
        new imgg = new Image() // Image()函数
        img.onload = function () {
            resolve(img) // 成功返回img
        }
        img.src = imgsrc
    })
}
// 请求图片时长
function timeout() {
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('请求超时')
        }, 3000) // 设置时长3秒
    })
    }
// 参数接受数组 请求成功不会走catch
Promise.rece([img('images/2.peg'), timeout()]).then(res => {
    console.log(res); // 如果3秒内请求图片就会执行这里
}).catch(err=>[
    console.log(err) // 如果3秒后才能请求到就会执行请求超时(打印请求超时提示)
])

race() finally(()=>{也是一个回调函数}) 不论是promise对象请求数据成功失败 都会执行race() finally()这两个方法

async异步

async 解决异步操作更加方便
使用async 进行异步操作 返回一个promise对象 可以统括then 和catch
async 时gemerator 的一个语法糖

1.案例使用async
async function f(){
    // 这个后台的字符串会被async方法转换为 promis对象
    // 字符传会被转换为promis对象
    // await命令就是等待
    return await 'await等待命令' async方法必须要与await配合使用
}
f() // Promise {<fulfilled>: undefined} 返回一个promise对象
f().then(res=>{ // 接受正确的数据
    console.log(res)
}).catch(error=>{ // 接受抛出异常数据
    console.log(error)
})


方便理解
async function f(){
    let s = await '你好 你好 async' //1.s变量执行
    let data = await s.split('') // 2.data 等待s变量执行完毕后 在进行执行
    return data // 3.最终返回的时data等待执行后的结果
  
}

// 假如:
async函数中有多个await 那么then函数等待 所有的await指令 运行完毕的结果 才会执行then

//注意:
await '后面必须是一个promise对象,不管是什么类型都会转换为promise对象'
await 特点就是 如果一个出错执行了错误信息,下面的await不会执行

2.捕获异常
async function f2(){
    await Promise.reject('出错了') // 只会打印出错了,下面的命令就不会执行
    await Promise.resolve('正确的') // 不执行

}
f2().then(
    (val)=>{
        console.log(val);
    }
).catch(
    (err)=>{
        console.log(err); // 捕获Promise对象的信息
    })


3.解决await 出现错误不执行的弊端
async function f2(){
    try {
        await Promise.reject('出错了') // 就算出错
    }catch(err){
    }
    return await Promise.resolve('正确的') // 还是可以出现正确的
}

f2().then(
    (val)=>{
        console.log(val); // 可以打印正确信息
    }
).catch(
    (err)=>{
        console.log(err); 
    })


4.模拟异步请求
function getJSON(url){
    //伪造的ajax请求
    console.log(url)
    return HeWeather6
}

// 伪造url 中返回的对象数据
HeWeather6 =  {
    now :{
        'xx':123
    }
}

//当执行这个函数时,就会将url传入到async的函数中
async function func(url) {
    // 发送ajax
    // await  等待数据传的返回
    let res = await getJSON(url) // 等待getJSON函数执行完毕后返回结果
    // 获取 url中的now的数据
    let arr = await res.now //HeWeather6 url 中返回的对象数据
    return arr // 返回数据 对象中now数据
}

// 使用then 获取正确的数据
// then 需要等待await执行完毕后返回的数据结构
func('这是url').then((val) => { console.log(val); })

总结:generator promise async 解决回掉地狱的问题(回掉循环 嵌套太多) 异步操作更加方便

class构造

class 关键字时es6的语法糖   
   
class Person{  // 创建class person
	constructor(name,age){ // init方法初始化方法
    	this.name = name // 赋值属性
    	this.age = age 
    }

	sayname(){ // 内部方法
		return this.name
	}
	sayage(){ // 内部方法
		return this.age
	}

}

let p1 = new Person('aa',123) // 实例化对象
console.log(p1); // Person {name: 'aa', age: 123}
// 调用对象中的方法
console.log(p1.sayage()); //123
console.log(p1.sayname()); //aa 

// 通过外部进行对类中设置方法 Object.assign 
// 传入两个参数1 当前的类名.prototype方法 2传入一个对象,对象中函数名(){}
Object.assign(Person.prototype,{
    sayxx(){
        return xx
    },
    sayzz(){
        return yy
    }
})

class类的继承

// 类的继承 使用关键字extends
// 创建类不用加上()

class animal {
    // es6 中的初始化方法 // 没有类对象
    constructor(name, age) {
        this.name = name //事例对象
        this.age = age // 事例对象
    }
    //创建两个对象
    show() {
        return this.name
    }
    func() {
        return this.age
    }
}
继承语法:
class  子类名 extends 父类名
class dog extends animal{
	// dog继承了adimal方法
}  

// 使用super方法继承父类的初始化方法
class dog extends animal{ 
    // 子类的初始化方法,因为继承了父类的变量
    constructor(name,age,color){
        super(name,age) // 直接使用super去找父类的变量就可以
        this.color = color
    }
    // 子类的自己的方法
    saycole(){
        return `${this.name}${this.age}`
    }
    //重写父类的方法
    func() {
        return `${this.name}${this.age}`
    }
}
// 创建子类的对象
let p1 = new dog('aa',18,'red') // p1是事例话dog 的对象
console.log(p1); // 返回了dog的对象,内部有父类的方法和父类的事例变量

//执行父类中的方法
console.log(p1.show());
//执行子类的方法
console.log(p1.color());

模块化

在modules/index.js文件将函数或者变量进行抛出

// es6 模块中主要有两个命令构成 export和import构成
// export 用于规定模块对外接口 抛出
// import 用于输入其他模块提供的功能 结构
// 模块就是一个独立的文件
export const name = '张珊'
export const age = 18
// 必须使用export关键字进行 
export function func(){ // 抛出方法对象
    return '你好我是xx'
}
// 或者
export {func} //抛出对象 被引用的进行解构

// 抛出类 对象 数组 等等


在需要的文件导入index.js文件中的变量和函数
<script type="module"> // 如果使用外部抛出的 模块需要将type设置为module
//  es6模块系统 引入 模块下的文件 和模块下的方法对象
// 进行解构 模块中的方法
import {name,age,func} from './modules/index.js' //进行导入 从那个文件导入那个变量
//  {name} 指定导出的数值或者方法  from 指定接受的文件
console.log(name)
console.log(age)
console.log(func());

</script>

补充

1.清空默认样式

/* @import "./iconfont.css"; */

/* 清除内外边距 */
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote,
dl, dt, dd, ul, ol, li,
pre,
fieldset, lengend, button, input, textarea,
th, td {
    margin: 0;
    padding: 0;
}
input {
    border: 0;
    outline: none;
    padding: 0;
    box-sizing: border-box;
}

img {
    vertical-align: middle;
}

/* 设置默认字体 */
body,
button, input, select, textarea { /* for ie */
    /*font: 12px/1 Tahoma, Helvetica, Arial, "宋体", sans-serif;*/
    font: 12px/1.3 "Microsoft YaHei",Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif; /* 用 ascii 字符表示,使得在任何编码下都无问题 */
    color: #333;
}


h1 { font-size: 18px; /* 18px / 12px = 1.5 */ }
h2 { font-size: 16px; }
h3 { font-size: 14px; }
h4, h5, h6 { font-size: 100%; }

address, cite, dfn, em, var, i{ font-style: normal; } /* 将斜体扶正 */
b, strong{ font-weight: normal; } /* 将粗体扶细 */
code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 统一等宽字体 */
small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */

/* 重置列表元素 */
ul, ol { list-style: none; }

/* 重置文本格式元素 */
a { text-decoration: none; color: #666;}


/* 重置表单元素 */
legend { color: #000; } /* for ie6 */
fieldset, img { border: none; }
button, input, select, textarea {
    font-size: 100%; /* 使得表单元素在 ie 下能继承字体大小 */
}

/* 重置表格元素 */
table {
    border-collapse: collapse;
    border-spacing: 0;
}

/* 重置 hr */
hr {
    border: none;
    height: 1px;
}
.clearFix::after{
    content:"";
    display: block;
    clear:both;
}
/* 让非ie浏览器默认也显示垂直滚动条,防止因滚动条引起的闪烁 */
html { overflow-y: scroll; }

a:link:hover{
    color : rgb(79, 76, 212) !important;
    text-decoration: underline;
}

/* 清除浮动 */
.clearfix::after {
    display: block;
    height: 0;
    content: "";
    clear: both;
    visibility: hidden;
}