Es6笔记

2021/05/05 共 12340 字,约 36 分钟

let关键字

1.变量不能重复声明
3.块级作用域
2.不存在变量提升
4.不影响作用域链

const关键字

1.一定要赋初始值
2.一般常量使用大写
3.常量的值不能修改
4.块级作用域
5.对于数组和对象的元素修改,不算做对常量的修改,不会报错

解构赋值

  • 数组的结构

      const f3 = ['1','2',3]
      let [xiao,liu,zhao] = f3;
      console.log(xiao)
    
  • 对象的解构

      const f3 = {name:'xiaoming',age:23, foo:function(){}}
      let {name, foo} = f3;
      console.log(name)
      foo();
    

模板字符串

ES6 引入了声明字符串的方式``;

1.内容中可以直接出现换行符
2.变量拼接
	let lovest = 'hello'
	let world = 'world'
	let out = `${lovest}${world}`
	let out = `${hello+world}`

简化对象写法

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

let name = '尚硅谷'
let change = function(){
	console.log('change')
}

const school = {
	name,
	change,
	improve: function(){
		console.log("我们可以提高你的技能")
	},
	improve1(){
		console.log("简洁的方法")
	}
}
console.log(school)

箭头函数

原始函数
let fn = function(){}
箭头函数
let fn = (a,b) = >{
	return a + b;
}
特性:
	1.this是静态的,this始终指向函数声明时所在作用域下的this的值
	2.不能作为构造实例化对象
	3.不能使用arguments变量
	4.箭头函数的简写
		1.省略小括号,当形参有且只有一个的时候
		2.省略花括号,当代码体只有一条语句的时候,此时return必须省略,而且
		语句的执行结果就是函数的返回值 
适合场景:与this无关的回调,定时器,数组的方法回调
不适合场景:与this有关的回调,比如事件回调,对象的方法

函数参数赋初始值

function add(a, b, c){
	return a + b + c;
}

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

与解构赋值结合
function connect({host, username, password, port=2203}){

}

connect({
	host: 'localhost',
	username: 'root',
	password: 'root',
	port: 3306
})

rest参数

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

ES5 获取实参的方式

function date(){
	//Arguments { 0: "白芷", 1: "小明", 2: "张三", … } 对象
	console.log(arguments)
}

date('白芷','小明','张三')

ES6 获取参数

function date(...args){
	//Array(3) [ "白芷", "小明", "张三" ]
	console.log(args)
}
date('白芷','小明','张三')

扩展运算符

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

const tfboys = ['易烊', '五湖', 'gg'];

function chunwan(){
	//Arguments { 0: "易烊", 1: "五湖", 2: "gg", … }
	console.log(arguments)
}

chunwan(...tfboys);

使用:
	数组的合并
    const kuaizi = ['1', 2];
    const fenghuang = ['3', '4'];
    const c = kuaizi.concat(fenghuang)
    const d = [...kuaizi, ...fenghuang]
    console.log(c)
    console.log(d)
    数组的克隆
    const fenghuang = ['3', '4'];
    const d = [...fenghuang]
    将伪数组转为真正的数组
    const divs = document.querySelectorAll("div");
    console.log(divs)//NodeList [ div#viewport, div#b]

    const divArr = [...divs]; //Array [ div#viewport, div#b ]
    console.log(divArr)

Symbol 基本使用

创建Symbol
let s = Symbol();

let s2 = Symbol('张三');

let s4 = Symbol.for('李四')

不能与其他数据进行运算
//USONB you are so niubility
//u undefined
//s string symbol
//o object
//n null number
//b boolean

symbol使用

给对象添加属性和方法,是独一无二的

	let game = {
        down: function(){
            console.log('game down')
        }
    }
    //声明一个对象
    let methods = {
        up: Symbol(),
        down: Symbol()
    }

    game[methods.up] = function(){
        console.log('up')
    }
    game[methods.down] = function(){
        console.log('down')
    }
    console.log(game.down())  //game down
    console.log(game[methods.down]()) //down

迭代器Iterator

Iterator是对象的属性

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

原生具备iterator接口的数据

  • Array
  • Arguments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList
const banji = {
    name: '一班',
    stus: [
        'xiaoming',
        'xiaoning',
        'xiaotian',
        'knight'
    ],
    [Symbol.iterator]: function () {
        let index = 0;
        const _this = this;
        return {
            next: function () {
                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 banji) {
    console.log(v)
}

生成器Generator

其实是一个特殊的函数

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

function* gen() {
        console.log(111)
        yield '一只没有耳朵';
        
        console.log(222)
        yield '一只没有尾部';
        
        console.log(333)
        yield '真奇怪'
    }
    let iterator = gen();

console.log(iterator)

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

生成器函数参数

function * gen(arg){
        console.log(arg)
        let one = yield 111;
        console.log(one)
        console.log(123)
    }

    let iterator = gen('aaa');

    console.log(iterator.next(666))
    console.log(iterator.next("333"))
//异步编程 文件操作 网络操作 数据库操作
    //1s 后控制台输出111,2s后输出 222 ,3s后输出333
    //回调地狱
    // setTimeout(() => {
    //     console.log(111);
    //     setTimeout(() => {
    //         console.log(222)
    //         setTimeout(() => {
    //             console.log(333)
    //         }, 3000);
    //     }, 2000);
    // }, 1000);

    function one() {
        setTimeout(() => {
            console.log(111)
            iterator.next();
        }, 1000);
    }

    function two() {
        setTimeout(() => {
            console.log(222)
            iterator.next();
        }, 2000);
    }

    function three() {
        setTimeout(() => {
            console.log(333)
            iterator.next();
        }, 3000);
    }

    function* gen() {
        yield one();
        yield two();
        yield three();
    }

    let iterator = gen();

    iterator.next();
//模拟获取 用户数据,订单数据,商品数据
    function getUsers() {
        setTimeout(() => {
            let data = '用户数据'
            iterator.next(data);
        }, 1000);
    }
    function getOrders(userData) {
        console.log(userData)
        setTimeout(() => {
            let data = '订单数据'
            iterator.next(data)
        }, 1000);
    }
    function getGoods(orderData) {
        console.log(orderData);
        setTimeout(() => {
            let data = '商品数据'
            // iterator.next();
            console.log(iterator.next())
        }, 1000);
    }

    function* gen() {
        let userData = yield getUsers();
        let orderData = yield getOrders(userData);
        let d = yield getGoods(orderData);
        console.log(d)
    }

    let iterator = gen();
    iterator.next();

Promise异步编程

语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

const p = new Promise(function (resolve, reject) {
        setTimeout(() => {
            // let data = '数据库中的用户数据'
            //resolve(data) 将状态修改为成功
            let data = '获取数据失败'
            reject(data); //将状态修改为失败
        }, 1000); 
    })
	//第一个回调函数状态为成功时调用,失败则调用第二个回调函数
    p.then(function (value) {
        console.log(value)
    }, function (reason) {
        console.log(reason)
    })
//读取文件
const fs = require('fs')

const p = new Promise(function (resolve, reject) {
    fs.readFile('./test1.txt', (err, data) => {
        //如果失败,则抛出错误
        if (err) reject(err);
        resolve(data)
    })
})

p.then(function(value){
    console.log(value)
},function(reason){
    console.log("读取失败")
})
//封装 ajax
const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();

        xhr.open("GET", "https://api.apiopen.top/getJoke");

        xhr.send();

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response)
                } else {
                    reject(xhr.response)
                }
            }
        }
    })

    p.then(function (value) {
        console.log(value)
    }, function (reason) {
        console.error(reason)
    })
const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('用户数据')
        }, 1000)
    })

    //调用then方法 then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
    //1.如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值对对象的成功的值 
    const result = p.then(value => {
        console.log(value)
        //1.非promise类型的属性
        // return 1111;

        //2.是promise对象,promise返回的值就是result的值 
        return new Promise((resolve, reject)=>{
            resolve('ok')
        })

        //3.抛出错误
        throw '出错啦';
    }, reason => {
        console.warn(reason)
    })

    console.log(result)

    //链式调用
    p.then(value=>{
        
    }).then(value=>{
        
    })
const fs = require('fs')

// //读取文件
// fs.readFile('./test.txt', (err1, data1) => {
//     //根据读取的文件再读取文件
//     fs.readFile('./test1.txt', (err1, data2) => {
//         let result = data1 + data2;

//         console.log(result.toString())
//     })
// })


//使用promise实现,解决回调地狱问题
const p = new Promise((resolve, reject) => {
    fs.readFile('./test.txt', (err, data) => {
        resolve(data);
    })
})

p.then(value => {
    //promise的状态就是p.then返回的状态
    return new Promise((resolve, reject) => {
        fs.readFile('./test1.txt', (err, data) => {
            resolve([value, data]);
        })
    })

}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile('./test2.txt', (err, data) => {
            value.push(data)
            resolve(data);
        })
    })
})

Set

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

//创建一个集合
let s = new Set();
let s2 = new Set([1, 2, 3, 1, 2])
//类型object
console.log(s, typeof s)
//元素个数 
console.log(s2.size)
//添加元素
s2.add('2')
//删除元素
s2.delete(2)
//是否有
console.log(s2.has(2))

console.log(s2)

// s2.clear();

for(let v of s2){
	console.log(v)
}
 let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
   let arr2 = [4, 5, 6, 5, 6]
   //1数组去重
   // let result = [...new Set(arr)];
   // console.log(result)
   //交集
   // let s2 = new Set(arr2);
   // let result = [...new Set(arr)].filter(item => s2.has(item))
   // console.log(result)
   //并集
   let union = [...new Set([...arr, ...arr2])];
   console.log(union)
   //差集

   let s2 = new Set(arr2);
   let diff = [...new Set(arr)].filter(item => !(s2.has(item)))
   console.log(diff)

Map

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

   let m = new Map()

   m.set("name", 'xiaoming')
   m.set("change", function () {
      console.log(change)
   })


   let key = {
      school : 'clsnull'
   }

   m.set(key, ['北京','上海'])

   // console.log(m.size)
   // m.delete(key)

   console.log(m.get(key))

   console.log(m.has(key))
   console.log(m.clear())
   console.log(m)

   for (const v of m) {
      console.log(v)//[k,v]
   }

class类

  function Phone(brand, price) {
      this.brand = brand;
      this.price = price;
   }

   Phone.prototype.call = function () {
      console.log('我可以打电话')
   }

   let huawei = new Phone('华为', 3000);
   console.log(huawei)
   huawei.call();

   class Phone {
      //构造方法 名字不能修改
      constructor(brand, price) {
         this.brand = brand;
         this.price = price;
      }

      //方法必须使用该语法,不能使用ES5的对象完整形式
      call() {
         console.log(this)
         console.log('我可以打电话!!')
      }
   }

   let mi = new Phone('xiaomi', '1999')
   console.log(mi)
   mi.call();

静态成员

   // function Phone() {

   // }
   // //下面两个是属于函数对象的,这样的属性称为静态成员
   // Phone.name = '手机';
   // Phone.change = function () {
   //    console.log("我可以改变")
   // }
   // console.log(Phone.name)

   // //实例对象没有函数对象(构造函数对象)上的属性和方法的
   // let nokia = new Phone();
   // //实例对象与原型对象是相通的

   // Phone.prototype.size = '5.5inch'
   // console.log(nokia.name)  //undefined
   // console.log(nokia.size) //5.5inch


   //+++++++++++++++++++++++++++++++++++++++++++++++++++
   class Phone {
      //静态成员
      static name = '手机';
      static change() {
         console.log('我可以改变世界')
      }
   }

   let nokia = new Phone();
   //不属性实例对象
   console.log(nokia.name); // undefined
   //属于类
   console.log(Phone.name); // '手机'

**ES5类的继承 **

   // 对象继承

   // 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('我可以拍照')
   }

   const mi = new SmartPhone('小米', 1000, '黑色', ' 5.5inch')
   console.log(mi)

ES6继承

  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("我可以拍照")
      }

      call() {
         console.log("对父类的重写我可以进行视频通话")
      }
   }

   let mi = new SmartPhone("小米", 3222, "红色", '3.4inch');
   console.log(mi)
   mi.call(); //对父类的重写我可以进行视频通话

getter和setter

   //get 和 set

   class Phone {
      get price() {
         console.log("价格的属性被读取了");
         return 'price'
      }

      set price(newVal){
         console.log("价格属性被修改了")
      }
   }

   let s = new Phone();
   s.price = 'free'

模块化

模块化的好处

  • 防止命名冲突
  • 代码利用
  • 高维护性

模块化规范产品

  • CommonJs => NodeJs、Browserify
  • AMD => requireJS
  • CMD => seaJ

模块化语法

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

  • export 命令用于规定模块的对外接口
  • import 命令用于输入其他模块提供的功能

基本使用

// m1.js
//分别暴露
export let school = 'java'

export function teach() {
    console.log("thach")
}
//统一暴露
let school = 'java'

function teach() {
    console.log("thach")
}

export {
    school,
    teach
}
//默认暴露

export default {
    school: 'sa',
    change: function () {
        console.log('change')
    }
}
<script type="module">
   import * as m1 from './m1.js'
   console.log(m1)
</script>
   //1.通用的导入方式
   // 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)
   // m3.default.change()

   //2.解构赋值形式
   // import { school, teach } from './m1.js'
   // import { school as s2, findJ } from './m2.js'
   // import { default as m3 } from './m3.js'
   // console.log(school)
   // console.log(s2)
   // console.log(teach)
   // console.log(m3)

   //3.简便形式,针对默认暴露
   import m3 from './m3.js'
   console.log(m3)

async和await

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

async函数

  • async函数的返回值为promise对象

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

      //async 函数 返回的是promise
            async function fn() {
               //返回的不是一个promise对象,则这个结果就是一个成功的promise对象
               // return 1;
               //    throw new Error("出错了") //返回的结果是一个失败的promise
        
               //返回的结果如果是一个promise对象 //如果这个promise对象成功了,则fn()也是成功的,返回的值就是promise成功的值 
               return new Promise((resolve, reject) => {
                  resolve("成功的数据 ")
                  reject("失败")
               })
            }
        
            const result = fn();
            console.log(result)
    

await表达式

  • await 必须写在async函数中
  • await 右侧的表达式一般为promise对象
  • await 返回的是promise成功的值
  • await 的promise失败了,就会抛出异常,需要通过try-catch捕获处理
const p = new Promise((resolve, reject) => {
         // resolve("成功的值 ")
         reject("失败")
      })
      async function fn() {
         try {

            let result = await p;
            console.log(result)
         } catch (e) {
            console.log(e)
         }
      }
      fn();

async和await

const fs = require("fs");

function readOne() {
    return new Promise((resolve, reject) => {
        fs.readFile('./1.txt', (err, data) => {
            if (err) reject(err)
            resolve(data)
        })
    })
}

function readTwo() {
    return new Promise((resolve, reject) => {
        fs.readFile('./2.txt', (err, data) => {
            if (err) reject(err)
            resolve(data)
        })
    })
}

function readThree() {
    return new Promise((resolve, reject) => {
        fs.readFile('./3.txt', (err, data) => {
            if (err) reject(err)
            resolve(data)
        })

        setTimeout(()=>{},100000)
    })
}

async function main() {
    let three = await readThree();
    let two = await readTwo();
    let one = await readOne();

    console.log(three.toString())
    console.log(one.toString())
    console.log(two.toString())
}

main();
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)
                  }
               }
            }
         })
      }

      async function main() {
         let result = await sendAjax("https://api.apiopen.top/getJoke")
         console.log(result)
      }

      let result = sendAjax("https://api.apiopen.top/getJoke")
      result.then(value => {
         console.log(value)
      })

对象展开和Rest

Rest参数与spread扩展运算符在es6中已经引入,不过es6只针对数组,

在es9中为对象提供了像数组一样的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: '天音波'
      }

      const skillTwo = {
         w: '金钟罩'
      }

      const mangseng = {
         ...skillOne,
         ...skillTwo,
         e: '天雷破'
      }

      console.log(mangseng)

文档信息

Search

    Table of Contents