尚硅谷---ES6

一、简介

1.1 ES介绍

ES全称ECMAScript,是脚本语言的规范。而平时经常编写的JavaScript,是ECMAScript的一种实现,所以ES新特性其实指的就是JavaScript的新特性

1.2 为什么要学习新特性?

1.语法简洁,功能丰富

2.框架开发应用

3.前端开发职位要求

二、ES6入门

2.1 let变量声明及声明特性

声明方式:

  let a
  let b,c,d
  let e=100
  let f=521,g='iloveyou',h=[]

声明特性:

1.变量不能重复声明(var可以重复声明)

2.块级作用域(全局、函数、eval)

  {
    let girl='周扬青'
  }
  console.log(girl) //Uncaught ReferenceError: girl is not defined

3.不存在变量提升

  console.log(song) //Uncaught ReferenceError: Cannot access 'song' before initialization
  let song='恋爱达人'

4.不影响作用域链

  {
    let school='尚硅谷'
    function fn(){
      console.log(school) //尚硅谷
    }
  fn()
  }

2.2 let经典案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <style>
    .item{
      width:100px;
      height:50px;
      border:1px solid #799;
      float:left;
      margin:0 20px;
    }
  </style>
</head>
<body>
  <div class="container">
    <h2 class="page-header">点击切换颜色</h2>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
<script>
    let items=document.getElementsByClassName('item')
    for(let i=0;i<items.length;i++){
      items[i].onclick=function(){
        console.log(i)
        items[i].style.background='pink'
      }
    }
</script>
</body>
</html>

 2.3 const 声明常量及特点

声明常量方式:

  const SCHOOL='尚硅谷'

声明特点:

1.一定要赋初值

  const A //Uncaught SyntaxError: Missing initializer in const declaration

2.一般常量使用大写(潜规则)

3.常量的值不能修改

  const SCHOOL='尚硅谷'
  SCHOOL='黑马程序员' //Uncaught TypeError: Assignment to constant variable.

4.块级作用域

  {
    const PLAYER='UZI'
  }
  console.log(PLAYER) //Uncaught ReferenceError: PLAYER is not defined

5.对于数组和对象元素的修改,不算做对常量的修改,不会报错

  const TEAM=['UZI','MXLG','MING','Letme']
  TEAM.push('Meiko')    //不会报错

2.4 变量的解构赋值

ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值

1.数组的解构

        数组的结构采用数组字面量的语法形式

        等号左边的变量通过在数组中的位置去取得等号右边的数组字面量相同位置的值

  const F4=['小沈阳','刘能','赵四','宋小宝']
  let [xiao,liu,zhao,song]=F4
  console.log(xiao) //小沈阳
  console.log(liu)  //刘能
  console.log(zhao) //赵四
  console.log(song) //宋小宝

2.对象的解构

        写法:{变量1,变量2,……,变量n}=对象

        注意:对象解构是按照属性名解构的,不管顺序。即属性名和变量名则相同解构

  const zhao={
    name:'赵本山',
    age:'不详',
    xiaopin:function(){
      console.log('我可以演小品')
    }
  }
  let {name,age,xiaopin}=zhao
  console.log(name) //赵本山
  console.log(age)  //不详
  console.log(xiaopin)  //function(){ console.log('我可以演小品') }
  xiaopin()  //我可以演小品

2.5 模板字符串

1.声明

  let str=`我也是一个字符串哦`
  console.log(str,typeof str) //我也是一个字符串哦 string

2.内容中可以直接出现换行符(单引号和双引号不能)

  let str=`
<ul>
    <li>沈腾</li>
    <li>马丽</li>
    <li>魏晨</li>
    <li>艾伦</li>
</ul>`
  console.log(str)
  /*
  *运行结果:
    <ul>
        <li>沈腾</li>
        <li>马丽</li>
        <li>魏晨</li>
        <li>艾伦</li>
    </ul>
  * */

3.变量拼接

        其中变量需要通过固定的形式 ${变量名} 进行拼接

  let lovest='魏晨'
  let out=`${lovest}是我心中最搞笑的演员`
  console.log(out) //魏晨是我心中最搞笑的演员

2.6 对象简化写法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法

  let name='尚硅谷'
  let change=function(){
    console.log('我们可以改变你')
  }
  const school={
    name,change
  }
  /*
  *等效的写法是:
  * const school={
  *       name:name,
  *       change:change
  * }
  * */

对象中的方法可以简化掉function关键字

  const school={
    improve(){
      console.log('我们可以提高你的技能')
    }
  }
    /*

     等价的写法是:

    const school={
        improve:function(){
            console.log('我们可以提高你的技能')
        }
    }

    */

2.7 箭头函数以及其声明特点

ES6允许使用箭头(=>)定义函数

  let fn=(name,age)=>{
    console.log(`我的名字是:${name},
我的年龄是:${age}`)
  }
  fn('林俊杰',34)
  /*
  *运行结果:
  *我的名字是:林俊杰,
  *我的年龄是:34
  * */

箭头函数特性:

       1. this是静态的,this始终指向函数声明时所在作用域下的this的值

  function getName(){
    console.log(this.name)
  }
  let getName2=()=>{
    console.log(this.name)
  }
  window.name='尚硅谷'
  const school={
    name:'atguigu'
  }
  getName() //尚硅谷
  getName2()  //尚硅谷
  getName.call(school) //atguigu
  getName2.call(school) //尚硅谷

        2.不能作为构造函数实例化对象

  let Person=(name,age)=>{
    this.name=name
    this.age=age
  }
  let p1=new Person('林俊杰','34') //Uncaught TypeError: Person is not a constructor

        3.不能使用arguments变量

  let fn=()=>{
    console.log(arguments)
  }
  fn(1,2,3) //Uncaught ReferenceError: arguments is not defined

        4.箭头函数的简写

                1)当形参有且只有一个时,可以省略小括号

  let add=n=>{
    console.log(n+n)
  }
  add(9) //18

                2)当代码体只有一条语句时,可以省略花括号

  let mul=n=>console.log(n*n)
  mul(5) //25

                省略花括号时,return也必须省略,而且此时语句的执行结果就是函数的返回值

  let add=n=>n+n
  console.log(add(6)) //12

2.8 箭头函数的实践与应用

  /*需求:
  *点击#ad 2s后颜色变为粉色
  * */
  let ad=document.getElementById('ad')
  ad.onclick=function(){
    setTimeout(()=>{
      this.style.background='pink'
    },2000)
  }

  /*
  *需求:
  * 从数组中返回偶数的元素
  * */
  const arr=[1,6,9,10,100,25]
  const result=arr.filter(item=>item%2===0)
  console.log(result)

箭头函数适合与this无关的回调、定时器、数组方法的回调

箭头函数不适合与this有关的回调、事件回调、对象的方法

2.9  函数参数的默认值设置

ES6允许给函数参数赋初始值

1.形参初始值        具有默认值的参数,一般位置要靠后(潜规则)

    function add(a,b=5,c=10){
        return a+b+c
    }
    let result=add(1,2)
    console.log(result) //13

2.与解构赋值结合

function connect({host='localhost',username,password,port}){
    console.log(host,username,password,port)
}
connect({
    host:'atguigu',
    username:'root',
    password:'123321',
    port:5500
})  //atguigu root 123321 5500

2.10 rest参数

ES6引入rest参数,用于获取函数的实参,用来代替arguments

function connect({host='localhost',username,password,port}){
    console.log(host,username,password,port)
}
connect({
    host:'atguigu',
    username:'root',
    password:'123321',
    port:5500
})  //atguigu root 123321 5500

rest参数必须放在最后

    function date(a,b,c,...args){
        console.log(a,b,c)
        console.log(args)
    }
    date(1,2,3,'阿Sa','柏芝','思慧')
    /*
    *运行结果:
    * 1 2 3
    * Array(3) ["阿Sa", "柏芝", "思慧"]
    * */

2.11 扩展运算符

...为扩展运算符,能将数组转换为逗号分隔的参数序列

    function date(a,b,c,...args){
        console.log(a,b,c)
        console.log(args)
    }
    date(1,2,3,'阿Sa','柏芝','思慧')
    /*
    *运行结果:
    * 1 2 3
    * Array(3) ["阿Sa", "柏芝", "思慧"]
    * */

2.12 扩展运算符的应用

1.数组的合并

    //1.数组的合并
    const kuaizi=['王太利','肖央']
    const fenghuang=['曾毅','玲花']
    const zxmzq=[...kuaizi,...fenghuang]
    console.log(zxmzq) //Array(4) ["王太利", "肖央", "曾毅", "玲花"]

2.数组的克隆

const sanzhihua=['E','G','M']
const clone=[...sanzhihua]
console.log(clone) //Array(3) ["E", "G", "M"]

3.将伪数组转换为真正的数组

    const divs=document.querySelectorAll('div')
    console.log(divs) //NodeList(3) [div, div, div]
    const divArr=[...divs]
    console.log(divArr) //Array(3) [div, div, div]

三、Symbol

3.1 Symbol基本使用

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值

它是JavaScript的第七种数据类型,是一种类似于字符串的数据类型

Symbol特点

1)Symbol的值是唯一的,用来解决命名冲突的问题

2)Symbol的值不能与其他数据类型进行运算

3)Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

    //创建 Symbol
    // 方式一
    let s=Symbol()
    console.log(s,typeof s) //Symbol() symbol
    // 方式二
    let s2=Symbol('尚硅谷')
    let s3=Symbol('尚硅谷')
    console.log(s2===s3) //false
    // 方式三
    let s4=Symbol.for('尚硅谷')
    console.log(s4,typeof s4) // Symbol(尚硅谷) symbol
    let s5=Symbol.for('尚硅谷')
    console.log(s4===s5) //true

3.2 对象添加Symbol类型的属性

方式一:

    // 向对象中添加方法 up down
    let game={}
    // 声明一个对象
    let methods={
        up:Symbol(),
        down:Symbol()
    }
    game[methods.up]=function(){
        console.log('我可以改变形状')
    }
    game[methods.down]=function(){
        console.log('我可以快速下降')
    }
    console.log(game)

方式二:

    let game={
        name:'狼人杀',
        [Symbol('say')]:function(){
            console.log('我可以发言')
        },
        [Symbol('zibao')]:function(){
            console.log('我可以自爆')
        }
    }
    console.log(game)

3.3 Symbol内置值

除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法

类型检测:Symbol.hasInstance

        当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法

    class Person{
        static [Symbol.hasInstance](param){
            console.log(o)
            console.log('我被用来检测类型了')
        }
    }
    let o={}
    console.log(o instanceof Person)

Symbol.isConcatSpreadable

        对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开

    const arr=[1,2,3]
    const arr2=[4,5,6]
    console.log(arr.concat(arr2)) //Array(6) [1, 2, 3, 4, 5, 6]
    arr2[Symbol.isConcatSpreadable]=false
    console.log(arr.concat(arr2)) //Array(4) [1, 2, 3, Array(3)]

四、迭代器

4.1 迭代器介绍

        迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口(就是一个属性),就可以完成遍历操作

1)ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费

2)原生具备iterator接口的数据(可用for of遍历)

        a)Array

        b)Arguments

        c)Set

        d)Map

        e)String

        f)TypedArray

        g)NodeList

3)工作原理

        创建一个指针对象,指向当前数据结构的起始位置

        第一次调用对象的next方法,指针自动指向数据结构的第一个成员

        接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员

        每调用next方法返回一个包含value和done属性的对象

注:需要自定义遍历数据的时候,要想到迭代器

    // 声明一个数组
    const west=['唐僧','孙悟空','猪八戒','沙僧']
    // 使用 for...of 遍历数组
    for(let v of west){
        console.log(v)
    }
    console.log(west)
    let iterator=west[Symbol.iterator]()
    console.log(iterator.next())
    console.log(iterator.next())
    console.log(iterator.next())
    console.log(iterator.next())
    console.log(iterator.next())

4.2 自定义遍历数据

    const class1={
        name:'终极一班',
        stus:[
            'xiaoming',
            'xiaoning',
            'xiaotian',
            'knight'
        ],
        [Symbol.iterator](){
            let index=0
            return {
                next:()=>{
                    if(index<this.stus.length){
                        const result={value:this.stus[index],done:false}
                        index++
                        return result
                    }else{
                        return {value:undefined,done:true}
                    }
                }
            }
        }
    }
    for(let v of class1){
        console.log(v)
    }

4.3 生成器函数的声明与调用

生成器其实就是一个特殊的函数

异步编程        纯回调函数        node  fs   ajax    mongodb

  function *gen(){
    console.log("hello generator")
  }
  let iterator=gen()
  console.log(iterator) //gen {[[GeneratorState]]: "suspended"}
  iterator.next() //hello generator

yield可以看做函数代码的分隔符用来暂停和恢复一个生成器函数(function*)

  function *gen(){
      console.log(111)
    yield '一直没有耳朵';
      console.log(222)
    yield '一直没有尾巴';
      console.log(333)
    yield '真奇怪'
      console.log(444)
  }
  let iterator=gen()
  iterator.next()
  iterator.next()
  iterator.next()
  iterator.next()
  iterator.next()
  for(let v of gen()){
      console.log(v)
  }

4.4 生成器函数的参数传递

在next函数中传递的参数会作为上一次调用next函数的返回值

    function *gen(arg){
        console.log(arg)
        let one=yield 111;
        console.log(one)
        let two=yield 222;
        console.log(two)
        let three=yield 333;
        console.log(three)
    }
    let iterator=gen('AAA')
    console.log(iterator.next())
    console.log(iterator.next('BBB'))
    console.log(iterator.next('CCC'))
    console.log(iterator.next('DDD'))

4.5 生成器函数实例

    let one=()=>{
        setTimeout(()=>{
            console.log(111)
            iterator.next()
        },1000)
    }
    let two=()=>{
        setTimeout(()=>{
            console.log(222)
            iterator.next()
        },1000)
    }
    let three=()=>{
        setTimeout(()=>{
            console.log(333)
            iterator.next()
        },1000)
    }
    function* gen(){
        yield one();
        yield two();
        yield three();
    }
    const iterator=gen()
    iterator.next()

4.6 生成器函数实例2

    let getUsers=()=>{
        setTimeout(()=>{
            let data='用户数据'
            iterator.next(data)
        },1000)
    }
    let getOrders=()=>{
        setTimeout(()=>{
            let data='订单数据'
            iterator.next(data)
        },2000)
    }
    let getGoods=()=>{
        setTimeout(()=>{
            let data='商品数据'
            iterator.next(data)
        },3000)
    }
    function* gene(){
        let users=yield getUsers();
        console.log(users)
        let orders=yield getOrders();
        console.log(orders)
        let goods=yield getGoods();
        console.log(goods)
    }
    let iterator=gene()
    iterator.next()

五、Promise

5.1 Promise简介

Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装一步操作并可以获取其成功或失败的结果

1)Promise构造函数:Promise(executor){}

2)Promise.prototype.then方法

3)Promise.prototype.catch方法

实例化promise时传入一个函数,有两个参数:resolve和reject

调用resolve封装数据则代表成功,调用reject封装数据则代表失败

实例化promise对象的then方法,可以传入两个函数,第一个对应resolve封装的数据,参数是value;第二个对应reject封装的数据,参数是reason

  //实例化 Promise
  const p=new Promise(function (resolve, reject){
    setTimeout(function(){
      let err='数据读取失败'
      reject(err)
    },1000)
  })
  //调用promise对象的then方法
  p.then(function(value){
    console.log(value)
  },function(reason){
    console.log(reason)
  })

5.2 Promise封装读取文件

//1.引入fs模块
const fs=require('fs')

//2.使用promise封装
const p=new Promise(function(resolve,reject){
    fs.readFile('./study.txt',(err,data)=>{
        if(err) reject(err)
        resolve(data)
    })
})

p.then(function(value){
    console.log(value.toString())
},function(reason){
    console.log('读取失败')
})

5.3 Promise封装AJAX操作

原生ajax:

    //1.创建对象
    const xhr=new XMLHttpRequest()
    //2.初始化
    xhr.open('GET','http://localhost:8080/getJoke')
    //3.发送
    xhr.send()
    //4.绑定事件,处理响应结果
    xhr.onreadystatechange=function(){
        if(xhr.readyState===4){
            if(xhr.status>=200&&xhr.status<300){
                console.log(xhr.response)
            }else{
                console.error(xhr.status)
            }
        }
    }

promise封装:

    const p=new Promise(function(resolve, reject){
        const xhr=new XMLHttpRequest()
        xhr.open('GET','http://localhost:8080/getJoke')
        xhr.send()
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4){
                if(xhr.status>=200&&xhr.status<300){
                    resolve(xhr.response)
                }else{
                    reject(xhr.status)
                }
            }
        }
    })
    p.then(function(value){
        console.log(value)
    },function(reason){
        console.log(reason)
    })

5.4 promise的then方法

then方法的返回结果是Promise对象,该对象状态由回调函数的执行结果决定

1.如果回调函数中返回的结果是非promise类型的属性,状态为成功,且返回值为对象的成功值(PromiseStatus:fulfilled)

2.如果返回的结果是promise对象,则返回值为该对象

3.抛出错误,PromiseResult即为抛出的错误

  //创建promise对象
  const p=new Promise((resolve,reject)=>{
    setTimeout(()=>{
      resolve('成功了')
      // reject('出错了')
    },1000)
  })
  //调用then方法
  const result=p.then(value=>{
    console.log(value)
    // return 123
    // return new Promise((resolve,reject)=>{
    //   reject('not ok')
    // })
    throw new Error('出错了')
  },reason=>{
    console.log(reason)
  })
  console.log(result)

链式调用

  p.then(value=>{},reason=>{}).then(value=>{},reason=>{})

5.5 Promise实践练习---多个文件内容读取

回调地狱版:

const fs=require('fs')

fs.readFile('./study.txt',(err,data1)=>{
    fs.readFile('./插秧诗.txt',(err,data2)=>{
        fs.readFile('./观书有感.txt',(err,data3)=>{
            let result=
                `${data1}
${data2}
${data3}
            `
            console.log(result)
        })
    })
})

Promise版:

const fs=require('fs')


const p=new Promise((resolve,reject)=>{
    fs.readFile('./study.txt',(err,data)=>{
        resolve(data)
    })
})

p.then(value=>{
    return new Promise((resolve,reject)=>{
        fs.readFile('./插秧诗.txt',(err,data)=>{
            resolve([value,data].join('\r\n'))
        })
    })
}).then(value=>{
    return new Promise((resolve,reject)=>{
        fs.readFile('./观书有感.txt',(err,data)=>{
            resolve([value,data].join('\r\n'))
        })
    })
}).then(value=>{
    console.log(value)
})

5.6 catch方法

用来指定promise失败的回调

const p=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        //设置p对象的状态为失败,并设置失败的值
        reject('出错了')
    },1000)
})
p.catch(reason=>{
    console.log(reason)
})

六、集合介绍与API

6.1 Set

ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for…of……进行遍历

集合的属性和方法:

1)size        返回集合的元素个数

2)add        增加一个新元素,返回当前集合

3)delete        删除元素,返回boolean值

4)has        检测集合中是否包含某个元素,返回boolean值

//声明一个set
let s=new Set()
let s2=new Set([1,2,3,4,5,6])

// 元素个数
console.log(s2.size)
// 添加新的元素
s2.add(9)
// 删除元素
s2.delete(5)
// 检测
console.log(s2.has(4))
// 遍历
for(let v of s2){
    console.log(v)
}
// 清空
s2.clear()

6.2 集合实践

let arr=[1,2,3,4,5,4,3,2,1]
// 1.数组去重
let result=[...new Set(arr)]
// 2.交集
let arr2=[4,5,6,5,4]
let r2=[...new Set(arr)].filter(item=>{
    let s2=new Set(arr2)
    return s2.has(item)
})
// 3.并集
let union=[...new Set([...arr,...arr2])]
// 4.差集
let diff=[...new Set(arr)].filter(item=>
    !new Set(arr2).has(item)
)

6.3 Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当键。Map也实现了iterator接口,所以可以使用扩展运算符和for...of...进行遍历

Map的属性和方法:

1)size        返回Map的元素个数

2)set        增加一个新元素,返回当前Map

3)get        返回键名对象的键值

4)has        检测Map中是否包含某个元素,返回boolean值

5)clear        清空集合,返回undefined

6)delete        根据键删除键值对

// 声明Map
let m=new Map()

// 添加元素
m.set('name','尚硅谷')
m.set('change',function(){
    console.log('我们可以改变你')
})
let key={
    school:'ATGUIGU'
}
m.set(key,['北京','上海','深圳'])
//size
console.log(m.size)
//删除
m.delete('name')
//获取
console.log(m.get('change'))
//遍历
for(let v of m){
    console.log(v)
}

七、Class

7.1 class介绍与初体验

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。

通过class关键字,可以定义类。基本上,ES6的class可以看做只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

知识点:

1)class声明类

2)constructor定义构造函数初始化

3)extends继承父类

4)super调用父级构造方法

5)static定义静态方法和属性

6)父类方法可以重写

ES5写法:

function Phone(brand,price){
    this.brand=brand
    this.price=price
}
Phone.prototype.call=function(){
    console.log('我可以打电话')
}
let Huawei=new Phone('华为',6988)
Huawei.call()
console.log(Huawei)

ES6写法:

class Phone{
    // 构造方法,名字不能修改
    constructor(brand,price) {
        this.brand=brand
        this.price=price
    }
    // 方法必须使用该语法,不能使用ES5的对象完整形式
    call(){
        console.log('我真的可以打电话')
    }
}
let onePlus=new Phone('1+',1900)
console.log(onePlus)
onePlus.call()

7.2 class静态成员

function Phone(){}
Phone.name='手机'
Phone.change=function(){
    console.log('我可以改变世界')
}
let nokia=new Phone()
console.log(nokia.name)
nokia.change()

 实例对象和函数对象的属性不互通

实例对象的属性和构造函数的原型对象相通

把属于类而不属于实例对象的属性称为静态成员

即,对于static标注的属性,属于类而并不属于对象

class Phone{
    static name ='手机'
    static change(){
        console.log('我可以改变世界')
    }
}
let nokia=new Phone()
console.log(nokia.name)
console.log(Phone.name)

7.3 ES5使用构造函数实现继承

function Phone(brand,price){
    this.brand=brand
    this.price=price
}
Phone.prototype.call=function(){
    console.log('我可以打电话')
}
function SmartPhone(brand,price,color,size){
    Phone.call(this,brand,price)
    this.color=color
    this.size=size
}
// 设置子级构造函数的原型
SmartPhone.prototype=new Phone
SmartPhone.prototype.constructor=SmartPhone

// 声明子类的方法
SmartPhone.prototype.photo=function(){
    console.log('我可以拍照')
}
SmartPhone.prototype.playGame=function(){
    console.log('我可以玩游戏')
}
const cz=new SmartPhone('锤子',2499,'黑色','5.5inch')
console.log(cz)

7.4 class类继承

class Phone{
    constructor(brand,price) {
        this.brand=brand
        this.price=price
    }
    call(){
        console.log('我可以打电话')
    }
}

class SmartPhone extends Phone{
    constructor(brand,price,color,size) {
        super(brand,price);
        this.color=color
        this.size=size
    }
    photo(){
        console.log('拍照')
    }
    playGame(){
        console.log('玩游戏')
    }
}
const xm=new SmartPhone('小米',7799,'red','5.5inch')
console.log(xm)
xm.call()

7.5 子类对父类方法的重写

class SmartPhone extends Phone{
    constructor(brand,price,color,size) {
        super(brand,price);
        this.color=color
        this.size=size
    }
    photo(){
        console.log('拍照')
    }
    playGame(){
        console.log('玩游戏')
    }
    call(){
        console.log('我可以进行视频通话')
    }
}

7.6 getter和setter的设置

class Phone{
    get price(){
        console.log('价格属性被读取了')
        return 'naomukiyo'
    }
    set price(newVal){
        console.log('价格属性被修改了:'+newVal)
    }
}
let s=new Phone()
console.log(s.price) //得到price的get方法返回值
s.price='free'

八、ES6扩展

8.1 ES6的数值扩展

1. Number.EPSILON是JavaScript能表示的最小精度

function equal(a,b){
    if(Math.abs(a-b)<Number.EPSILON){
        return true
    }
    return false
}

console.log(0.1+0.2===0.3)  //false
console.log(equal(0.1+0.2,0.3)) //true

2. 二进制和八进制

let b=0b1010    //二进制
let o=0o777     //八进制
let d=100   //十进制
let x=0xff  //十六进制

3. Number.isFinite        检测一个数值是否为有限数

    console.log(Number.isFinite(100))   //true
    console.log(Number.isFinite(100/0)) //false
    console.log(Number.isFinite(Infinity)) //false

4. Number.isNaN        检测一个数值是否为NaN

    console.log(Number.isNaN(123)) //false
    console.log(Number.isNaN('abc')) //false

5.Number.parseInt 和 Number.parseFloat 字符串转整数

    console.log(Number.parseInt('123px')) //123
    console.log(Number.parseFloat('3.141589m')) //3.14159

6.Number.isInteger 判断一个数是否为整数

    console.log(Number.isInteger('123')) //false
    console.log(Number.isInteger(23)) //true

7.Math.trunc 将数字的小数部分抹掉

    console.log(Math.trunc(4.67)) //4

8.Math.sign 判断一个数到底是正数、负数还是零

    console.log(Math.sign(100)) //1
    console.log(Math.sign(0))   //0
    console.log(Math.sign(-100)) //-1

8.2 对象方法的扩展

1.Object.is 判断两个值是否完全相等        类似于完全等于===

    console.log(Object.is({name:"尚硅谷"},{name:"尚硅谷"})) //false

2.Object.assign        对象的合并

        该方法传递两个参数,如果属性值一样,后面的会将前面的相同属性的属性值覆盖

const config1={
    host:'localhost',
    port:3306,
    name:'root',
    password:'root'
}
const config2={
    host:'http://atguigu.com',
    port:33060
}
console.log(Object.assign(config1,config2))
/*
*运行结果:
*host = "http://atguigu.com"
*port = 33060
*name = "root"
*password = "root"
*
* */

3.Object.setPrototypeOf 设置原型对象

Object.getPrototypeOf

const school={
    name:'尚硅谷'
}
const cities={
    xiaoqu:['北京','上海','深圳']
}
Object.setPrototypeOf(school,cities)
console.log(Object.getPrototypeOf(school)) //Object {xiaoqu: Array(3)}
console.log(school) //Object {name: "尚硅谷"}

九、模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来

9.1 模块化的好处

模块化的优势有以下几点:

1)防止命名冲突

2)代码复用

3)高维护性

9.2 模块化规范产品

ES6之前的模块化规范有:

1)CommonJS => NodeJS、Browserify

2)AMD => requireJS

3)CMD => seaJS

9.3 ES6模块化语法

模块功能主要由两个命令构成:export和import

export命令用于规定模块的对外接口

import命令用于输入其他模块提供的功能

0.分别暴露

export let school='尚硅谷'

export function teach(){
    console.log('我们可以教给你开发技能')
}
<script type="module">
    import * as m1 from './index.js'
    m1.teach() //我们可以教给你开发技能
    console.log(m1.school) //尚硅谷
</script>

9.4 ES6模块暴露数据语法汇总

1.统一暴露

let school='尚硅谷'

function findJob(){
    console.log('我们可以帮助你找工作')
}

export {school,findJob}
<script type="module">
    import * as m2 from './index.js'
</script>

2.默认暴露

export default{
    school:'ATGUIGU',
    change(){
        console.log('我们可以改变你')
    }
}
<script type="module">
    import * as m3 from './index.js'

    console.log(m3.default.school) //ATGUIGU
    m3.default.change() //我们可以改变你
</script>

9.5 ES6引入模块数据语法汇总

1.通用的导入方式

    import * as m3 from './index.js'

2.解构赋值的形式

<script type="module">
    import {school,teach} from './index.js'
    teach() //我可以教你技术
</script>

解构赋值中如果遇到属性值同名,可以使用as起别名

    import {school,teach} from './index.js'
    import {school as guigu,findJob} from './m3.js'

当遇到使用default默认暴露,可以对default起别名

export default {
    school:'atguigu',
    change(){
        console.log('我们可以改变你')
    }
}
<script type="module">
    import {default as m3} from './index.js'
    m3.change()
</script>

3.简便形式        但只能针对默认暴露

<script type="module">
    import m3 from './index.js'
    m3.change()
</script>

9.6 浏览器使用ES6模块化方式二

// 模块引入
import * as m1 from './m1.js'
import * as m2 from './m2.js'
import * as m3 from './m3.js'

console.log(m1)
console.log(m2)
console.log(m3)
<script src="./app.js" type="module"></script>

9.7 babel对ES6模块化代码的转换

1.安装工具 babel-cli babel-preset-env browserify(实际项目中用webpack)

npm i babel-cli babel-preset-env browserify -D 

2.如果是局部安装babel,则需要用npx进行转换

第一个参数:js文件原先所在目录

第二个参数:转换后的js文件所在目录

 npx babel es6 -d dist --presets=babel-preset-env

 3.打包 npx browserify dist/index.js -o dist/bundle.js

npx browserify dist/index.js -o dist/bundle.js

9.8 ES6模块化引入NPM包

1.安装jQuery

 npm i jquery

2.导入jQuery包

import $ from 'jquery' //等价于 const $=require('jquery')

3.编写代码,修改背景颜色为粉色

$('body').css('background','pink')

4.重新打包

npx babel es6 -d dist --presets=babel-preset-env
npx browserify dist/app.js -o dist/bundle.js

5.html中引入对应的打包文件

<script src="../dist/bundle.js" type="module"></script>

十、ECMAScript7 新特性

Array.prototype.includes :

        includes方法用阿里检测数组中是否包含某元素,返回布尔类型值

    const mz=['西游记','红楼梦','三国演义','水浒传']
    console.log(mz.includes('西游记')) //true
    console.log(mz.includes('金瓶梅')) //false

指数操作符:

        在ES7中引入指数运算符**,用来实现幂运算,功能和Math.pow结果相同

    console.log(2**10) //1024

十一、ECMAScript8 新特性

11.1 async和await

async和await两种语法结合可以让异步代码像同步代码一样

async函数:

        async函数的返回值为promise对象

        promise对象的结果由async函数执行的返回值决定

await表达式:

        await必须写在async函数中

        await右侧的表达式一般为promise对象

        await返回的是promise成功的值

        await的promise失败了,就会抛出异常,需要通过try...catch捕获处理

async:

1.async函数中,只要返回的结果不是一个Promise类型的对象,则该函数的返回值就是一个成功的Promise

async function fn(){
    return '尚硅谷'
}

console.log(fn()) //Promise {[[PromiseState]]: "fulfilled", [[PromiseResult]]: "尚硅谷"}

2.如果抛出错误,则返回的结果是一个失败的Promise

3.返回的结果如果是一个Promise对象,则成功与否由这个Promise对象决定

await:

    const p=new Promise((resolve, reject)=>{
        // resolve('用户数据')
        reject('失败了')
    })
    async function fn(){
        try{
            let result=await p
            console.log(result)
        }catch(e){
            console.log(e)
        }
    }

11.2 async和await结合读取文件内容

const fs=require('fs')

let read=(filePath)=>{
    return new Promise((resolve,reject)=>{
        fs.readFile(filePath,(err,data)=>{
            if(err) reject(err)
            resolve(data)
        })
    })
}

async function fn(){
    let r1=await read('./为学.txt')
    console.log(r1.toString())
    let r2=await read('./插秧诗.txt')
    console.log(r2.toString())
    let r3=await read('./观书有感.txt')
    console.log(r3.toString())
}

fn()

11.3 async和await结合发送AJAX请求

    function sendAJAX(url){
        return new Promise((resolve,reject)=>{
            const x=new XMLHttpRequest()
            x.open('GET',url)
            x.send()
            x.onreadystatechange=function(){
                if(x.readyState===4){
                    if(x.status>=200&&x.status<300){
                        resolve(x.response)
                    }else{
                        reject(x.status)
                    }
                }
            }
        })
    }
    // promise then 方法测试
    // const result=sendAJAX('http://localhost:8000/server').then(value=>{
    //     console.log(value)
    // })

    //async await测试
    async function main(){
        let result=await sendAJAX('http://localhost:8000/server')
        console.log(result)
    }

 11.4 ES8对象方法扩展

Object.values和Object.entries

        1.Object.values()方法返回一个给定对象的所有可枚举属性值的数组

        2.Object.entries()方法返回一个给定对象自身可遍历属性[key,value]的数组

Object.getOwnPropertyDescriptors

        该方法返回指定对象所有自身属性的描述对象

    const school={
        name:'尚硅谷',
        cities:['北京','上海','深圳'],
        subjects:['前端','Java','大数据','运维']
    }
    //获取对象所有的键
    console.log(Object.keys(school))
    //获取对象所有的值
    console.log(Object.values(school))
    //entries
    console.log(Object.entries(school))
    const m=new Map(Object.entries(school))
    console.log(m)
    //对象属性的描述对象
    console.log(Object.getOwnPropertyDescriptors(school))

    const obj=Object.create(null,{
        name:{
            value:'尚硅谷',
            writable:true,
            enumerable:true,
            configurable:true
        }
    })

 

十二、ECMAScript9

12.1 扩展运算符与rest参数

Rest参数与spread扩展运算符在ES6中已经引入,不过ES6中只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符

rest参数:

    function connect({host,port,...user}){
        console.log(host)
        console.log(port)
        console.log(user)
    }
    connect({
        host:'127.0.0.1',
        port:3306,
        username:'root',
        password:'root',
        type:'master'
    })

 

扩展运算符:

    const skillOne={
        q:'天音波',
        w:'金钟罩'
    }
    const skillTwo={
        e:'天雷破'
    }
    const skillThree={
        r:'猛龙摆尾'
    }
    //如果使用扩展运算符...skillOne,则解构为 q:'天音波',w:'金钟罩'
    const ms={...skillOne,...skillTwo,...skillThree}
    console.log(ms) //Object {q: "天音波", w: "金钟罩", e: "天雷破", r: "猛龙摆尾"}

12.2 正则扩展---命名捕获分组

没有命名捕获分组时:

  //声明一个字符串
  let str="<a href='http://www.atguigu.com'>尚硅谷</a>"
  //提取url与标签文本
  const reg=/<a href='(.*)'>(.*)<\/a>/
  const result=reg.exec(str)
  console.log(result)
  console.log(result[1])

 

有命名分组捕获时:

        命名分组语法:

                ?<任意名字>

  //声明一个字符串
  let str="<a href='http://www.atguigu.com'>尚硅谷</a>"
  //提取url与标签文本
  const reg=/<a href='(?<url>.*)'>(?<text>.*)<\/a>/
  const result=reg.exec(str)
  console.log(result)
  console.log(result.groups.url)
  console.log(result.groups.text)

 

12.3 正则扩展---反向断言

( )

标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)

.匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。

用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。

() 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。

以下列出 ?=、?<=、?!、?<! 的使用区别

exp1(?=exp2):查找 exp2 前面的 exp1。

(?<=exp2)exp1:查找 exp2 后面的 exp1。

exp1(?!exp2):查找后面不是 exp2 的 exp1

(?<!exp2)exp1:查找前面不是 exp2 的 exp1

  //声明字符串
  let str='JS5201314你知道吗555啦啦啦'
  //正向断言
  const reg=/\d+(?=啦)/
  const result=reg.exec(str)
  console.log(result) //555

  //反向断言
  const reg1=/(?<=吗)\d+/
  const result1=reg1.exec(str)
  console.log(result1) //555

12.4 正则扩展---dotAll模式

        dot,即.        元字符,表示除换行符以外的任意单个字符

正则表达式-修饰符:

s特殊字符圆点 . 中包含换行符 \n默认情况下的圆点 . 是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。
  let str=`
<ul>
    <li>
        <a>肖申克的救赎</a>
        <p>上映日期:1994-09-10</p>
    </li>
    <li>
        <a>阿甘正传</a>
        <p>上映日期:1994-07-06</p>
    </li>
</ul>
  `
  const reg=/<li>.*?<a>(?<name>.*?)<\/a>.*?<p>(?<time>.*?)<\/p>/gs
  let result
  while(result=reg.exec(str)){
    console.log(result.groups.name,result.groups.time)
  }

十三、ECMAScript10

13.1 对象扩展方法Object.fromEntries

功能:接收一个二维数组或一个Map来创建数组

  //二维数组
  const result=Object.fromEntries([
          ['name','尚硅谷'],
          ['subjects','JAVA,大数据,前端,云计算']
  ])
  console.log(result) //Object {name: "尚硅谷", subjects: "JAVA,大数据,前端,云计算"}
  //Map
  const m=new Map()
  m.set('name','atguigu').set('age',20)
  const r=Object.fromEntries(m)
  console.log(r) //Object {name: "atguigu", age: 20}

该方法和Object.entries()互为逆运算,Object.entries()可以将对象转换为二维数组

  const arr=Object.entries({
    name:'尚硅谷',
    subjects:'JAVA,大数据'
  })
  console.log(arr) //Array(2) [Array(2), Array(2)]

13.2 字符串方法扩展---trimStart和trimEnd

trimStart()清除字符串开头的空格

trimEnd()清除字符串结尾的空格

  let str='       i love you       '
  console.log('----'+str+'----')
  console.log('----'+str.trimStart()+'----')
  console.log('----'+str.trimEnd()+'----')

 

13.3 数组方法扩展---flat和flatMap

flat()可以将高维数组转换为低维数组,默认每次降低一个维度

  const arr1=[[1,2],[4,5]]
  console.log(arr1.flat()) //Array(4) [1, 2, 4, 5]
  const arr2=[[[1,2],[3,4]],[[5,6],[7,8]]]
  console.log(arr2.flat()) //Array(4) [Array(2), Array(2), Array(2), Array(2)]

可以传递一个参数,代表深度

  const arr2=[[[1,2],[3,4]],[[5,6],[7,8]]]
  console.log(arr2.flat(2)) //Array(8) [1, 2, 3, 4, 5, 6, 7, 8]

flatMap:它会遍历原数组的每一个元素, 并且会为每个元素都执行一次传入的回调函数,最终把所有元素执行回调函数返回的结果压缩成一个新数组,flatMap会返回一个新的数组,不会改变原数组的元素。

  const arr=[1,2,3,4]
  const result=arr.flatMap(item=>[item*10])
  console.log(result) //Array(4) [10, 20, 30, 40]
  //对比map
  const result1=arr.map(item=>[item*10])
  console.log(result1) //Array(4) [Array(1), Array(1), Array(1), Array(1)]

13.4 Symbol.prototype.description

得到Symbol的描述值

  let s=Symbol('尚硅谷')
  console.log(s.description) //尚硅谷

十四、ECMAScript11

14.1 私有属性

#开头声明,表示私有属性

只能在类的内部访问,而不能通过外部访问

class Person{
  name
  #age
  #weight
  constructor(name,age,weight){
    this.name=name
    this.#age=age
    this.#weight=weight
  }
  intro(){
    console.log(this.name,this.#age,this.#weight)
  }
}
let girl=new Person('小丽',23,'41kg')
console.log(girl) //Person {#age: 23, #weight: "41kg", name: "小丽"}
// console.log(girl.#age) Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
girl.intro() //小丽 23 41kg

14.2 Promise.allSettled方法

allSettled方法的返回值始终是成功的

参数是多个Promise构成的数组,返回值中包含每一个Promise的状态的结果

  const p1=new Promise((resolve,reject)=>{
    setTimeout(()=>{
      resolve('商品数据-1')
    },1000)
  })
  const p2=new Promise((resolve,reject)=>{
    setTimeout(()=>{
      reject('出错了')
    },1000)
  })
  const result=Promise.allSettled([p1,p2])
  console.log(result)

 和Promise.allSettled很像的一个方法是Promise.all,但是Promise.all方法需要所有的Promise都成功才会返回成功,否则失败

14.3 String.prototype.matchAll方法

用来得到正则批量匹配的结果,在正则匹配提取数据方面非常实用

    let str=`
<ul>
    <li>
        <a>肖申克的救赎</a>
        <p>上映日期:1994-09-10</p>
    </li>
    <li>
        <a>阿甘正传</a>
        <p>上映日期:1994-07-06</p>
    </li>
</ul>
  `
    let reg=/<li>.*?<a>(?<name>.*?)<\/a>.*?<p>(?<time>.*?)<\/p>/sg
    const result=str.matchAll(reg)
    for(let v of result){
        console.log(v.groups.name,v.groups.time)
    }
// 运行结果
// 肖申克的救赎 上映日期:1994-09-10
// 阿甘正传 上映日期:1994-07-06

14.4 可选链操作符

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。

?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空( nullish ) ( null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。

与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

function main(config){
    const dbHost=config?.db?.host
    console.log(dbHost) //127.0.0.1
}
main({
    db:{
        host:"127.0.0.1",
        port:3306
    },
    cache:{
        host:"192.168.1.200",
        username:"admin"
    }
})

 

14.5 动态import

静态引入:不管未来是否需要使用,直接先引入进来

动态引入:通过import()函数,传递模块路径,返回结果为一个Promise对象。同时这个Promise对象成功的值就是动态引入的模块所暴露的对象

document.getElementById('btn').onclick=function(){
    import('./hello.js').then(module=>{
        module.hello()
    })
}

14.6 BigInt类型

只需要在数字后面加上n即代表BigInt类型

主要用于大数值运算

    //大整形
    let n=521n
    console.log(n,typeof n) //521n bigint
    //函数
    let n1=23
    console.log(BigInt(n1))
    let max=Number.MAX_SAFE_INTEGER
    console.log(max+1) //9007199254740992
    console.log(max+2) //9007199254740992
    console.log(BigInt(max)+BigInt(1)) //9007199254740992n
    console.log(BigInt(max)+BigInt(2)) //9007199254740993n

14.7 全局对象globalThis

方便对全局对象操作,支持nodejs环境


完结撒花❀❀~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值