ES6~ES13

ES6~ES13

定义变量

  1. let

    • 不能在定义之前访问

    • 变量不能重定义

    • 块级作用域,包含if语句,switch语句等,不限于函数块

      简易选项卡案例改进

      ·<!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <style>
              * {
                  margin: 0;
                  padding: 0;
              }
      
              ul {
                  list-style: none;
              }
      
              .header {
                  display: flex;
                  width: 500px;
              }
      
              .header li {
                  flex: 1;
                  height: 50px;
                  line-height: 50px;
                  text-align: center;
                  border: 1px solid black;
              }
      
              .box {
                  position: relative;
              }
      
              .box li {
                  position: absolute;
                  left: 0;
                  top: 0;
                  width: 500px;
                  height: 200px;
                  background-color: yellow;
                  display: none;
              }
      
              /*      给第一个样式先来个激活状态 */
              .header .active {
                  background-color: orange;
              }
      
              .box .active {
                  display: block;
              }
          </style>
      </head>
      
      <body>
          <ul class="header">
              <li class="active">1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
          </ul>
          <ul class="box">
              <li class="active">111</li>
              <li>222</li>
              <li>333</li>
              <li>444</li>
          </ul>
          <script>
              var headerItems = document.querySelectorAll(".header li")
              var boxItems = document.querySelectorAll(".box li")
              //用for循环给每li添加自定义属性标识,并且设置标题的点击事件
              //用let定义,每次循环都是新的i
              for (let i = 0; i < headerItems.length; i++) {
                  /* headerItems[i].dataset.index=i; */
                  headerItems[i].onclick = handler
      
                  //点击事件函数
                  function handler() {
                      //辨识点击哪个标题
                      var index = i
                      //移除激活类名
                      for (var m = 0; m < headerItems.length; m++) {
                          headerItems[m].classList.remove("active")
                          boxItems[m].classList.remove("active")
                      }
                      //添加激活状态
                      headerItems[index].classList.add("active")
                      boxItems[index].classList.add("active")
                  }
              }
          </script>
      </body>
      
      </html>
      
  2. const:定义后作为常量存在,不能再重新赋值,不能只定义不赋值

    应用于网页中一些作为参考的数据

  3. let块级作用域案例:最常用的情景

解构赋值

快速从对象和函数中获取里面的成员

  1. 数组

    var arr=["1","2","3"]
    let[x,y,z]=arr
    console,log(x,y,z)
    
  2. 对象

    var obj={
       name:"1",
       age:"2",
       location:"3"
    }
    //因为location变量名已经被window占用,不能重名,可以自己用冒号重命名
    let {name,age,location:mylocation}=obj
    console.log(name)
    console.log(age)
    console.log(mylocation)
    

字符串模板

``${}`:大括号内是一个小型的函数环境,他会被编译

字符串扩展

includes函数

判断字符串中是否存在指定字符

第二个参数是可选的,当写上后查询时不包含此下标

字符串名.includes(“查询字符”,参数)参数后是否包含
字符串名.startswith(“查询字符”,参数)参数后的第一个下标是否是查询字符
字符串名.endswith(“查询字符”,参数)参数前最后一个下标是否是查询字符

repeat函数

将原字符串重复n次返回一个新字符串

字符串名.repeat(整数)
字符串名.repeat(小数)会自动取整
字符串名.repeat(0)空字符串

数值扩展

可以编译二进制与八进制

isFinite,isNaN方法

  1. isNaN() 判断不是数字

  2. isFinite() 判断是数字

  3. isFinite() 有两个方法 : isFinite() 和 Number.isFinite()

    • Number.isFinite() 与全局的 isFinite() 函数不同

      全局的 isFinite() 会先把检测值转换为 Number ,然后在检测。

      Number.isFinite() 不会将检测值转换为 Number对象,
      如果检测值不是 Number 类型,则返回 false。

isInteger方法

Number.isInteger(数)用来判断一个数值是否为整数。

JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值。

极小常量Number.EPSILON

是 JavaScript 能够表示的最小精度。误差如果小于这个值,就可以认为已经没有意义了,即不存在误差了。

Math方法扩展

  1. Math.trunc方法用于去除一个数的小数部分,返回整数部分。

    • 内部使用Number方法将其先转为数值。
    • 对于空值和无法截取整数的值,返回NaN
    • 对于负数取整,他会选取数值较小的那个
  2. Math.sign方法用来判断一个数到底是正数、负数、还是零。

    对于非数值,会先将其转换为数值。

    它会返回五种值。

    • 参数为正数,返回+1
    • 参数为负数,返回-1
    • 参数为 0,返回0
    • 参数为-0,返回-0;
    • 其他值,返回NaN

数组扩展

展开运算符…

  1. 展开拼接

    var a=[1,2,3]
    var b=[4,5,6]
    拼接两数组
    //conlose.log(a,concat(b))
    var c=[...a,...b]
    
  2. 展开复制

    var a=[1,2,3]
    //var b=a.slice()
    //var b=a.concat()
    var b=[...a]
    b[0]="ha"
    
  3. 参数-实参-形参

    • 解决arguments不能用于箭头函数的问题
    var test=(...arr)=>{
    console.log(arguments)
    }
    test(1,2,3,4)
    
    • a对应1,b对应2,…arr对应[3,4,5]

      而且…arr放在最后最后一个参数

    var test=function(a,b...arr)=>{
    console.log(arr)
    }
    test(1,2,3,4,5)
    
    • 找出后端所传数据的最值
    var arr=[1,2,3,4,5,6,7,8,9]
    var res=Math.max(...arr)
    
    • 伪数组转换
    function test(){
    var arr=[...arguments]
    console.log(arr)
    }
    test(1,2,3,4,5)
    

Array.from

将伪数组转为真正的数组

// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).map(function () {
});

// arguments对象
function foo() {
  var args = Array.from(arguments);
  }

Array.of

将一组值,转换为数组。

因为参数个数的不同,会导致Array()的行为有差异。

Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

Array.of(3) // [3]
Array.of(3, 11, 8) // [3,11,8]

数组实例的 find() 和 findIndex()

  1. find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的

    1. 成员,则返回undefined。
    [1, 4, -5, 10].find((n) => n < 0)
    // -5
    [1, 5, 10, 15].find(function(value, index, arr) {
      return value > 9;
    }) // 10
    //find方法的回调函数可以接受三个参数,依次为当前的值、下标和原数组。
    
  2. findIndex方法,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。

    [1, 5, 10, 15].findIndex(function(value, index, arr) {
      return value > 9;
    }) // 2
    这两个方法都可以接受第二个参数,用来绑定回调函数的this对象。
    
  3. findLast,findLastIndex:逆序寻找

fill方法

fill方法可以填充一个数组。

fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

flat,flatMap方法

数组降维操作

var newArray = arr.flat(参数)

//不传递参数的时候默认为一层
let arr = [1,2,[3,[4,[5]]]]
const reasut = arr.flat()
console.log(reasut)
// [1, 2, 3, [4,[5]]]
//传递参数
const reasut2 = arr.flat(3)
console.log(reasut2)
// [1, 2, 3, 4, 5]
//传入Infinity时,相当于扁平化最深层次的数组
const reasut3 = arr.flat(Infinity)
console.log(reasut3)
// [1, 2, 3, 4, 5]
//当数组里面有空项的时候,会过滤掉空值
const arr2 = [1, , 2, [3]]
const reasut4 = arr2.flat()
console.log(reasut4)
// [1, 2, 3]

对象扩展

属性简写

var obj={getname:getname}
可以写成
var obj={getname

var obj={getName:function(){}}
可以写成
var obj={getName(){}}

属性名表达式

定义对象的属性,有两种方法。

  1. 直接用标识符作为属性名

  2. 用表达式作为属性名

    将表达式放在方括号之内

    let obj = { [a]: 123 }
    let a=module
    //obj = { module: 123 }
    

扩展运算符…

可以将一个对象转为用逗号分隔的参数序列之中。

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
  1. 注意:如果扩展运算符后面是一个空对象,则没有任何效果。
    如果扩展运算符后面不是对象,则会自动将其转为对象。
    如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象。
    对象的扩展运算符等同于使用Object.assign()方法。
    扩展运算符可以用于合并两个对象。

  2. 对象的合并

    • …方法

      新建一个新的数组,合并的对象如果有相同的键名,那么后面对象对应的属性值会覆盖前面对象对应的属性值 ,属性值是最后一次赋值的值;

      语法:Obj = {...o1,...o2,...o3,...o4}

    • Object.assign

      将后面的的数组合并到第一个数组上

      语法:Object.assign(o1,o2,o3)

  3. 对象的复制

    语法:newObj = {...oldObj}

     let o1 = {
        name:"张三",
        age:18
    };
    //(1)赋值的是引用,指向的是同一个对象;
    let o2 = o1;
    console.log(o2,o2===o1);
    //{name: "张三", age: 18} true
    //(2)复制对象,两个是不同的对象:
    let o3 = {...o1};
    console.log(o3,o3===o1);
    //{name: "张三", age: 18} false
    

Object.is()

  1. 双等号==

    将执行类型转换,

  2. 三等号

    不进行类型转换(如果类型不同, 只是总会返回 false)

  3. Object.is

    基本上与三等号相同,但是对于NaN和-0和+0进行特殊处理

    Object.is(NaN,NaN)将为 true,在=====中将是false

函数扩展

函数的默认参数

普通函数和箭头函数均适用

//当调用函数时忘记传参,会使用默认值
function test(a=1.b=2){
return a+b
}

剩余参数…

用于获取函数的多余参数,这样就不需要使用arguments对象了。

// arguments 变量的写法
function sortNumbers(){
  return Array.prototype.slice.call(arguments).sort();
}

// rest 参数的写法
const sortNumber = (...numbers) => number.sort();

name属性

返回函数的函数名

function foo() {}
foo.name // "foo"

箭头函数

  1. 语法:var 变量=(0=>{})

    • 只有一个形参的时候可以省略()

    • 当大括号内只有一句代码或只有返回值,{}与return可以省略

      var newlist =list.map(function(item){
      return `<li>${item}</li>`
      })
      //可以转化为
      var newlist =list.map(item=>`<li>${item}</li>`)
      

      当{}里面只有一个对象时,不省略{}

    • arguments:没办法用箭头函数

      在函数没有形参的情况下,调用函数时传实参给函数,在函数内使用此关键字可以得到所传实参的伪数组。

      var test=function(){
      console.log(a,b,c)
      console.log(arguments[0],arguments[1],arguments[2])
      //转化为真数组
      console.log(Array.from(arguments))
      })
      test(1,2,3)
      
    • 箭头函数的this指向父级作用域的

      //如果直接在计时器内用this,会指向window,所以用that在外面暂存this
      mytext.oninput=function(){
      var that=this
      setTimeout(()=>{
      console.log(that.value)
      },1000)
      }
      //箭头函数可以直接指向外面的父级元素
      mytext.oninput=function(){
      setTimeout(()=>{
      console.log(this.value)
      }1000)
      }
      

案例:用户数据修改

    <input type="text" id="myusername">
    <input type="tel" id="myage">
    <button id="btn">修改</button>
    <div id="box"></div>
    <script>
        //后端数据
        var obj = {
            name: "xiaohong",
            age: 100,
            location: "guangdong",
            id: "2154285424252"
        }
        //后端数据渲染
        function render({name,age,location}) {
            box.innerHTML = `name${name},age${age},location:${location}`
        }
        render(obj)
        btn.onclick=function(){
            var name=myusername.value
            var age=myage.value
            var newobj={
                ...obj,
                name,
                age
            }
            //重新渲染
            render(newobj)
        }
    </script>

模块化语法

  1. 模块化之前的痛点

    引用js文件时

    • 私密代码依然会被访问
    • 会出现变量名重复
    • 多个js文件互相引用会出现一定的顺序依赖
  2. 模块化语法——私密不怕

    分两步

    • 外部js文件导出:

      export{
      a,b,c...//你想被别人导入的函数名
      }
      
    • 本文件导入:

      <script type="module">
        import{a,b,c...你想导入的函数名} from `文件路径`
      </script>
      之后便可以直接调用函数
      
  3. 模块化语法——重名不怕

    • 文件导入:

      <script type="module">
        import{a,重名函数 as 重命名} from `文件路径`
      </script>
      之后便可以直接调用函数-以重命名方式
      
  4. 模块化语法——依赖不乱

    分两步

    • 在外部js文件中先引入需要的其他js文件

      <import>{...}from`路径`
      之后便可以直接调用函数
      
    • 本文件导入时引入顺序可以不按顺序

Symbol

Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值,用于保护变量属性

  1. 创建语法:

    let a = Symbol(); 
    console.log(a);
    //Symbol()
    
  2. 作为属性:

    • 赋值与读取语法:

      let keys={
      name:Symbol(),
      age:Symbol(),
      test:Symbol()
      }
      let obj={
      [keys.name]:"haha",
      [keys,age]:100
      [keys.test](){
      console.log("test")
      }
      }
      //通过obj找到test方法并执行
      obj[keys.test]()
      
    • 另外,可以对Symbol传参,目的是为了使属性更清晰

      let keys={
      name:Symbol(name),
      age:Symbol(age),
      test:Symbol(test)
      }
      
    • for in只能遍历出普通属性,不能遍历symbol属性Object.getOwnPropertySymbols(对象名)可以遍历symbol属性

      Reflect.ownKeys(对象名)`可以遍历普通属性与symbol属性

    //用reflect获得属性与属性值
    Reflect.ownKeys(对象名).forEach(item=>{
    console.log(item,obj[item])
    })
    
  3. 作为常量

    例如:
    const VIDEO=symbol()
    const IMAGE=symbol()
    function play(type){
    switch(type){
    case VIDEO:
    console.log("视频")
    break;
    case IMAGE
    console.log("图片")
    break;
    }
    }
    play(IMAGE)
    

Iterator迭代器

为各种数据结构提供统一的,简便的访问接口,js可以为它执行如for…of,map(),filter()等迭代方法

原生具备Iterator接口的数据结构

  • Array

  • Map

  • Set

  • String

  • TypedArray

  • 函数的 arguments 对象

  • NodeList 对象

原理

  1. 得到遍历对象,本质是一个指针对象
  2. 调用next方法,指针指向数据结构的第一个成员
  3. next方法调用之后会返回一个对象,这个对象有2个属性
    • value 是本次迭代的返回值。
    • done 是一个bool值,迭代结束的标识,结束就是true

for…of例子

  1. 语法

    for(var i of [1,2,3]){
    	console.log(i);
    }
    
  2. 原因:数据身上有 iterator方法,而这个方法可以通过被[Symbol.iterator]内置属性引用。

  3. 内部机制:

    const arr=["a","b","c"]
    //引出iterator
    const iter=arr[Symbol.iterator]()
    console.log(iter)
    //调用next方法遍历
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    

手动实现iterator迭代器

对象是非线性的,无序列化的,所以大多数对象不能用for of遍历

…展开运算符,遇到有迭代器的对象使用时会自动转化为数组

let obj = {
    code: 200,
    name: "obj",
    list: ["a", "b", "c"],
    //迭代器
    [Symbol.iterator]() {
         let index = 0
          return {
               next: () => {
                        return {
                            value:  this.list[index++],
                            done: index === (this.list.length + 1) ? true : false
                        }
                }
          }
     }
}
//for of遍历功能实现
for (let i of obj) {
            console.log(i);
}
//...展开转换为数组
console。log([...obj])
//观察next返回
const iter = obj[Symbol.iterator]()
console.log(iter)
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())

Set结构

类似于数组,但成员值唯一不重复,主要用于为数组去重

let s=new Set([1,2,3,3,4])
//返回值是一个对象1,2,3,4
//转化为数组
console。log([...s])
  1. 属性

    set结构.size:获取长度

  2. 方法

    • set结构.add().add().add():添加值,可以链式添加
    • set结构.has(值):判断有没有某个值
    • set结构.delete(值):删除值
    • set结构.clear():清空数组
  3. 遍历

    因为set结构没有索引记住,所以健名就是键值

    • forEach

    • for(let i of set结构{}:遍历每个成员

    • for(let i of set结构.keys(){}:返回键名的遍历器

    • for(let i of set结构.values(){}:返回键值的遍历器

    • for(let i of set结构.entries(){}:返回每对键值与键名成数组的遍历器

      对于数组使用此方法

      let arr=["aa","bb","cc"]
      for(let i of arr.entries()){
      console,log(i)
      }
      //[0:"aa"]
      //[1:"bb"]
      //[2:"cc"]
      let arr=["aa","bb","cc"]
      for(let [index,item] of arr.entries()){
      console,log(index,item)
      }
      //0:"aa"
      //1:"bb"
      //2:"cc"
      
  4. 复杂数组去重

    let list=[1,2,3,"haha","haha",[1,2],[3,4],[1,2],{name:"haha"},{name:"haha"},undefined,undefined]
    function uni(arr){
    let res=new Set()
    return arr.filter((item)=>{
    //将每一项转化为字符串判断
    let id=JSON.stringify(item)
    if(res.has(id)){
    return false
    }
    else{
    res.add(id)
    return true
    }
    })
    }
    console.log(uni(list))
    

Map结构

类似于对象,是键值对的集合,各种类型的值都可以当做键

let m=new Map([
["name","haha"],
["age",100],
[{a:1},"大连"]
])
console.log(m2)
//转化为数组
console.log([...m])
  1. 属性与方法

    • size

    • set

    • delete

    • has

    • clear

    • set结构.get(键名):获取键,当键名是一个对象时用变量名引用

      例如
      let o={a:1}
      let m=new Map([
      [o,"大连"]
      ])
      console.log(m.get(o))
      
  2. 遍历:键名与键值不一样

    keys(),values(),entries(),for of

    forEach

    m.forEach((item,index)=>{
    console.log(item,index)
    })
    

Proxy代理

Proxy 在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写

        let obj = {}
        //参数:代理对象,get(),set()       
        let proxy = new Proxy(obj, {
            get() {
                console.log("get")
            },
            set() {
                console.log("set")
            }
        })
        //对代理proxy进行设置才有效
        //proxy.a
        //get
        //undefined
        //proxy.a="a"
        //set
        //'a'

Reflect对象

Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,它提供了一些方法与Proxy中方法一致。

定义,修改一个对象的属性

Reflect.get(target,name,receiver)

const obj = {
};
Reflect.defineProperty(obj, 'name', {
    value: 'haha',
    writable: false,
    configurable:false
});

Reflect对象的方法与Proxy对象的方法一一对应

只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法

let target = new Set()
const proxy = new Proxy(target, {
    get(target, key) {
        const value = Reflect.get(target,key)
        if (value instanceof Function) {
            console.log(`${value}`)
            return value.bind(target)
            //不能 是 call apply 
        }
        return value
    },
    set() {
        return Reflect.set(...arguments)
    }
})
proxy.add(1)

promise

专门解决回调地狱

  • 语法

    每一个异步事件,在执行的时候都会有三个状态:执行中 / 成功 / 失败

    借助成功状态,用Promise解决回调地狱

    代码理解:

new Promise(function (resolve, reject) {
  ajax({
    url: '1',
    success (res) {
      resolve(res)
    }
  })
}).then(function (res) {
  // 发送第二个请求
  return new Promise(function (resolve, reject) {
    ajax({
      url: '2',
      data: { a: res.a, b: res.b },
      success (res) {
        resolve(res)
      }
    })
  })
}).then(function (res) {
  ajax({
    url: '3',
    data: { a: res.a, b: res.b },
    success (res) {
      console.log(res)
    }
  })
})

Generator 函数

封装的异步任务,或者说是异步任务的容器

执行 Generator 函数会返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

使用 yield 表达式,定义不同的内部状态

function *gen(){
    console.log(1)
    yield;
    console.log(2)
    yield;
    console.log(3)
}
let g = gen()
g.next()
g.next()
g.next()

Class

基础语法

class Person {
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.log(this.name,this.age)
    }
}
let obj = new Person("haha",100)
console.log(obj)

getter与setter

class List{
    constructor(ele){
        this.element = ele
    }

    get html(){
        return this.element.innerHTML
    }
    set html(arr){
        this.element.innerHTML = arr.map(item=>`<li>${item}</li>`).join("")
    }
}
let obj = new List(document.querySelector("#list"))

obj.html = ["a","b","c"]

静态属性与方法

静态属性和静态方法
class Person {
    static name = "person"
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.log(this.name,this.age)
    }

    static p(){
        console.log("eat")
    }
}
let obj = new Person("kerwin",100)

console.log(Person.name)
Person.p()

Class继承

注意:子类必须在constructor()方法中调用super(),否则就会报错。

class Person {
    static name = "person"
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.log(this.name,this.age)
    }

    static eat(){
        console.log("eat")
    }
}
class Student extends Person{
    constructor(name,age,score){
        super(name,age)
        this.score = score
    }
    say(){
        super.say()
        console.log(this.score)
    }

    static p(){
        super.eat();
        console.log("student eat")
    }
}
let obj = new Student("zzy",100,200)
console.log(obj)
obj.say()
Student.p()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值