Bootstrap

ES6-11语法万字简单总结,看这个就够了,持续更新中...

什么是ES?

我们经常说到的ES5、ES6到底指的是什么?

  • ES是指ECMAScript,它是脚本语言的规范。而平时我们经常编写的JavaSript,是ECMAScript的一种实现,所以ES新特性其实指的就是JavaScript的新特性。我们所学的JS基础应该都是基于ES5(早在2009年12月份ECMA公司就发布了ECMAScript5),而我们嘴边所说的ES6是在2015年发布的,之后每年ECMA都会更新迭代新版本的ES,不过之后的每一版改动的内容不多。
  • 我们会发现,现在关于前端的招聘信息中,要求能够熟练掌握ES6语法的技能已经是最为普遍的要求。我认为从ES5到ES6的版本迭代,是非常有意义的。我们会发现ES6在前端工程化过程中起到了很重要的推动作用。
  • 关于前端发展的历史,这里就不过多介绍,如果感兴趣的话,可以自己去搜索,网上有很详细的讲解。下面的简单介绍中,我尽量用代码举例。
  • 注意:为了节省时间,下面的代码实例中变量命名未遵循代码规范,请各位小朋友不要模仿,平时一定要注意命名规范!!!

ES6 新特性

1. let声明变量
let a;
let b,c,d;
let e=100;
let f=521,g='aaa',h=[];
1.1 变量不能重复声明
let star='周杰伦';
let star='林俊杰';
// Identifier 'star' has already been declared
1.2 块级作用域(主要指的是全局作用域、函数作用域、eval)
 let star='林俊杰';
 {
        let star='周杰伦';
        console.log(star);
  }
   console.log(star)
   // 周杰伦
   // 林俊杰
1.3 不存在变量提升
var people;
console.log(people);
let people="aaa";
//Identifier 'people' has already been declared
// 如果是var 这里会是undefined
1.4 不影响作用域链
{
            let song='青花瓷';
            fn=()=>{
                console.log(song);
            }
            fn();
            //青花瓷
}
2. const 声明常量
const star='周杰伦';

注意:

  • 一定要赋初始值,不然会报错
  • 一般常量是用大写
  • 常量的值不能改变
  • 遵顼块级作用域
  • 对于数组和对象的元素修改,不算做对常量的修改,这里不会报错
3. 解构赋值

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

3.1 数组的解构
const sdtw=['刘德华','郭富城','张学友','黎明'];
let [first,second,thrid,forth]=sdtw;
console.log(first,second,thrid,forth);
//刘德华,郭富城,张学友,黎明
3.2对象的解构赋值
const zhao={
            name:'赵本山',
            age:'不详',
            xiaopin:()=>{
                console.log('演小品');
            }
        };
let {name,age,xiaopin}=zhao;
console.log(name,age);
xiaopin();
//赵本山 不详
//演小品
4. 模板字符串

ES6中引入新的声明字符串的方式 => ``

4.1 声明
let str=`我也是一个字符串哦`;
console.log(str,typeof(str));
//我也是一个字符串哦   string
4.2 内容中可以直接出现换行符
let str=`<ul>
                    <li>沈腾</li>
                    <li>玛丽</li>
                    <li>魏翔</li>
                    <li>艾伦</li>
          </ul>`;
4.3 变量拼接
 let star='沈腾';
 let out =`${lovest}是一个喜剧演员`;
 console.log(out);
 //沈腾是一个喜剧演员
5.简化对象写法

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

 let name='aaa';
 let change=()=>{
     console.log('你猜我是谁');
 }
 const school={
	        name,change,
	        improve(){
	            console.log('xxxx');
	        }
	    }

在这里插入图片描述

6.箭头函数
6.1 声明
 let fn=function(a,b){
            return a+b;
        }
 let fn1=(a,b)=>{
      return a+b;
  }
 console.log(fn(1,2));
 console.log(fn1(1,2));
 //3
 //3
6.2 关于this

this是静态的,箭头函数的this始终指向函数声明时所在作用域下的this值,也就是没有自己的this,指向外层的this。

 window.name='学习ES6';
  function getName(){
      console.log(this.name);
  }
  let getName2=()=>{
      console.log(this.name)
  }
  const school={
      name:'学习很快乐'
  }
  getName();
  //学习ES6
  getName2();
  //学习ES6
  
  // call方法调用,证明箭头函数没有自己的this
  getName.call(school);
  //学习很快乐
  getName2.call(school);
  //学习ES6
6.3不能作为构造函数实例化对象
//ES5中声明构造函数并实例化对象
let Person=function (name,age){
            this.name=name;
            this.age=age;
        };
 let person=new Person('xiaoming',20);
 console.log(person);
 //Person {name: "xiaoming", age: 20}
 
 let Person=(name,age)=>{
            this.name=name;
            this.age=age;
        }
 let person=new Person('xiaoming',20);
 //Person is not a constructor
6.4不能使用arguments(函数内部特殊的实参)变量
let fn=function(){
            console.log(arguments)
        }
 fn(1,2,3);

在这里插入图片描述

 let fn=()=>{
            console.log(arguments)
        }
 fn(1,2,3);
 //arguments is not defined
6.5 箭头函数的简写
//1)省略小括号,当形参有且只有一个的时候
let add=n=>{
                return n+n;
            }
 console.log(add(9));
 //18
 // 2)省略花括号,当代码体只有一句语句的时候,此时return必须省略
 let pow=n=>n*n;
 console.log(pow(8));
 //64
7.参数默认值

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

7.1 形参初始值

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

function add(a,b,c=10){
            return a+b+c;
        }
 let result=add(1,2);      //如果不传c结果为NaN
 console.log(result);
 //13
7.2 与解构赋值结合
function connect({host,username,password,port}){
            console.log(host,username,password,port);
            //localhost root root 3306
        }
 connect({
        host:'localhost',
        username:'root',
        password:'root',
        port:3306
    })
8. rest参数

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

// ES5 获取实参的方式
function date(){
     console.log(arguments)
 }
 date('白芷','阿娇','思慧');

在这里插入图片描述

// rest参数((...)扩展运算符在下一个知识点)
function date(...args){
     console.log(args);
 }
 date('白芷','阿娇','思慧');
 //["白芷", "阿娇", "思慧"]
 
 // rest 参数必须要放到参数最后
 function date(a,b,...args){
      console.log(a,b,args);
  }
  date(1,2,3,4,5);
  //1 2 [3, 4, 5]
9. 扩展运算符

[…]扩展运算符能将【数组】转化为逗号分隔的【参数序列】

9.1 基本使用
const tfboys=['易烊千玺','王源','王俊凯'];
const tfboys=['易烊千玺','王源','王俊凯']; 
// 声明一个函数,使用arguments参数
function chunwan(){
    console.log(arguments);
}
chunwan(tfboys);
chunwan(...tfboys);  //=>chunwan('易烊千玺','王源','王俊凯');

在这里插入图片描述

9.2 数组的合并
const kuaizi=['王太利','肖央'];
const fenghuang=['曾毅','玲花'];
const zuixuanxiaopingguo=kuaizi.concat(fenghuang);
console.log(zuixuanxiaopingguo);
//["王太利", "肖央", "曾毅", "玲花"]
const zuixuanxiaopingguo=[...kuaizi,...fenghuang];
console.log(zuixuanxiaopingguo);
//["王太利", "肖央", "曾毅", "玲花"]
9.3 数组的克隆
const sanzhihua=['E','G','M'];
const sanyecao=[...sanzhihua];
 console.log(sanzhihua);
 //["E", "G", "M"]
9.4 将伪数组转化为真正的数组
<div></div>
<div></div>
<div></div>
<script>
	 const divs=document.querySelectorAll('div');
	 const divArr=[...divs];
	 console.log(divArr);
	 //[div, div, div]
</script>
10. Symbol

ES6引入了一种新的原始数据类型Symbol,用来表示独一无二的值。它是JavaScript语言的第七种语言类型,是一种类似于字符串的数据类型
Symbol的特点:

  • 1)Symbol值是唯一的,用来解决命名冲突的问题
  • 2)Symbol值不能与其他数据类型进行运算
  • 3)Symbol定义的对象属性不能使用for…in循环遍历获取对象键名,但是可以使用Reflect.ownKeys来获取对象的所有键名
10.1 创建基本Symbol
let s=Symbol();
console.log(s,typeof(s));
//Symbol() "symbol"
10.Symbol.html:22 false
let s2=Symbol('爱学习');
let s3=Symbol('爱学习');
console.log(s2===s3);
//false
10.2 Symbol.for创建
let s4=Symbol.for('爱学习');
let s5=Symbol.for('爱学习');
console.log(s4,s5,typeof(s4),typeof(s5));
//Symbol(爱学习) Symbol(爱学习) "symbol" "symbol"
10.3 不能与其它数据进行运算
//let result=s+100;
//let result=s>100;
let result=s+s;
//Cannot convert a Symbol value to a number
10.4 Symbol创建对象属性
 let game={
            contene:'text'
        }
//声明一个对象
 let methods={
     up:Symbol(),
     down:Symbol()
 };
 game[methods.up]=function(){
     console.log('我可以改变形状');
 }
 game[methods.down]=function(){
     console.log('我可以快速下降');
 }
 console.log(game);

在这里插入图片描述

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

在这里插入图片描述

10.5 Symbol内置属性
//扩展对象功能
class Person{
            static [Symbol.hasInstance](param){
                console.log(param);      //传递的o
                //{}
                console.log('我被用来检测类型了'); 
                //我被用来检测类型了
            }
        }
let o={};
console.log(o instanceof Person)        //判断是否是该构造函数的实例化对象
// false
//阻止数组合并
const arr=[1,2,3];
const arr2=[4,5,6];
arr2[Symbol.isConcatSpreadable]=false; 
console.log(arr.concat(arr2));

在这里插入图片描述

11. 迭代器

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

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的next()方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用next()方法,指针一直往后移动,直到指向最后一个成员
  4. 每调用next()方法返回一个包含value和done属性的对象
11.1 简单的迭代器之for…of…
const xiyou=['唐僧','孙悟空','猪八戒','沙僧'];
for(let v of xiyou){
            console.log(v);
        }
 //唐僧
 //孙悟空
 //猪八戒
 //沙僧
11.2 迭代器自定义遍历对象
//声明一个对象
 const banji={
            name:'终极一班',
            stus:[
                '小明',
                '小天',
                '小宁',
                '小花'
            ],
            [Symbol.iterator](){
                //索引变量
                let index=0;
                return {
                //重写迭代器中的next()函数
                    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 banji){
       console.log(v)
   }
 //小明
 //小天
 //小宁
 //小花
12. 生成器函数

生成器其实就是一个特殊的函数,函数名前加’ * ’

function * gen(){
             console.log(111);
             console.log(222);
             console.log(333);
             console.log(444);
        }
let iterator=gen();   //=>迭代器对象
console.log(iterator)
iterator.next();
iterator.next();
iterator.next();
iterator.next();

在这里插入图片描述

function * gen(){
            yield '一只没有耳朵';
            yield '一只没有尾巴';
            yield '真奇怪';
        }
for(let v of gen()){
        console.log(v)
    }
//一只没有耳朵
//一只没有尾巴
//真奇怪
12.1 生成器函数参数
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());
  // next方法可以传入实参,这个参数将作为上一个yield的返回结果
  console.log(iterator.next('BBB'));
  console.log(iterator.next('CCC'));
  console.log(iterator.next('DDD'));

在这里插入图片描述

12.2 生成器函数举例
 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();
   //实现每隔1、2、3秒输出
   //111
   //222
   //333
 // 模拟获取(利用计时器函数代替真实获取数据的ajax的请求)  用户数据  订单数据  商品数据
 function getUser(){
     setTimeout(()=>{
         let data='用户数据';
         // 调用next方法,并将数据传入
         iterator.next(data);
     },1000);
 }

 function getOrders(){
     setTimeout(()=>{
         let data='订单数据';
         iterator.next(data);
     },1000);
 }

 function getGoods(){
     setTimeout(()=>{
         let data='商品数据';
         iterator.next(data);
     },1000);
 }

 function * gen(){
     let users=yield getUser();
     console.log(users);
     let orders=yield getOrders();
     console.log(orders);
     let goods=yield getGoods();
     console.log(goods);
 };
 let iterator=gen();
 iterator.next();
13. Promise

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

13.1 Promise基本语法
  const p=new Promise((resolve,reject)=>{
            setTimeout(() => {
                let data='数据库中的用户数据';
                resolve(data);
                let err='数据读取失败';
                reject(err);
                //一个请求要么成功要么失败,所以要么返回成功结果,要么返回失败结果。成功时默认返回成功数据
            }, 1000);
        })
  p.then(value=>{
        console.log(value);
        //数据库中的用户数据
    },reason=>{
        console.log(reason);
        //数据读取失败
    })
13.2 Promise-then方法
 // 创建 promise对象
    const p=new Promise((resolve,reject)=>{
        setTimeout(() => {
            resolve('用户数据');
            // reject('出错了');
        }, 3000);
    })
     // 调用then 方法 ,then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
     
    const result=p.then(value=>{
         console.log(value);
         //用户数据
         // 1.非 promise类型的属性
         // 如果回调函数中返回的结果是  非promise 类型的属性,状态为成功,返回值为对象的成功值
         // return 123;
         // 2.是promise对象
         //则遵循promise对象的方式
         // return new Promise((resolve,reject)=>{
         //     resolve('ok');
         // });

         // 3.抛出错误
         throw new Error('出错了');
         //Error: 出错了
     },reason=>{
         console.error(reason);
     })
     console.log(result);
14. 集合(Set)

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

  1. size:返回集合的元素个数
  2. add:增加一个新元素,返回当前集合
  3. delete:删除元素,返回boolean值
  4. has:检测集合中是否包含某个元素,返回boolean值
let s=new Set();
let s2=new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);
console.log(s2);
//Set(4) {"大事儿", "小事儿", "好事儿", "坏事儿"}
// 元素个数
 console.log(s2.size)
 //5
 // 添加新的元素
 s2.add('喜事儿');
 console.log(s2);
 //Set(5) {"大事儿", "小事儿", "好事儿", "坏事儿","喜事儿"}
 // 删除元素
 s2.delete('坏事儿');
 console.log(s2);
 //Set(4) {"大事儿", "小事儿", "好事儿","喜事儿"}
 // 检测 
 console.log(s2.has('好事儿'));
//true
 // 清空
 s2.clear();
 console.log(s2)
 //Set(0) {}

 for(let v of s2){
            console.log(v)
        }
//集合的简单应用
let arr=[1,2,3,4,5,6,5,4,3,2,1];
let arr2=[4,5,6,5,6];

//数组去重
let result=[...new Set(arr)];
console.log(result);
//(6) [1, 2, 3, 4, 5, 6]

//求两个数组的交集
let result=[...new Set(arr)].filter(item=>new Set(arr2).has(item))
console.log(result);
//(3) [4, 5, 6]

//求两个数组的并集
let union=[...new Set([...arr,...arr2])];
console.log(union);
//(6) [1, 2, 3, 4, 5, 6]

//两个数组的差集
let diff=[...new Set(arr)].filter(item=>!(new Set(arr2).has(item)));
console.log(diff);
//(3) [1, 2, 3]
15. Map

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

  1. size:返回Map的元素个数
  2. set:增加一个新元素,返回当前Map
  3. get:返回键名对象的键值
  4. has:检测Map中是否包含某个元素,返回boolean值
  5. clear:清空,返回undefined
// 声明Map
let m = new Map();
// 添加元素
m.set('name','周杰伦');
m.set('change',function(){
    console.log('我可以改变你');
})

let key={
    school:'清华大学'
};
m.set(key,['北京','上海','深圳']);
console.log(m);

在这里插入图片描述

//接着上面的
console.log(m.size);
//3
// 删除
m.delete('name');
console.log(m)
//Map(2) {"change" => ƒ, {…} => Array(3)}

// 获取
console.log(m.get('change'));
 //ƒ (){
 //       console.log('我可以改变你');
 // }

 // 清空
 m.clear();
 console.log(m);
 //Map(0) {}
 
 // 遍历
 for(let v of m){
     console.log(v);
 }
 
16. Class

ES6提供了更接近传统语言的写法,引入了Class类这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大多数部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

 // ES5通过构造函数实例化对象
  //手机
  // function Phone(brand,price){
  //     this.brand=brand;
  //     this.price=price;
  // }
  // //添加方法
  // Phone.prototype.call=function(){
  //     console.log('我可以打电话');
  // }
  // // 实例化对象
  // let Huawei=new Phone('华为',5999);
  // Huawei.call();
  // console.log(Huawei);

// ES6中使用class
class Phone{
     // 构造方法 名字不能修改
     constructor(brand,price){
         this.brand=brand;
         this.price=price;
     }
     // 方法必须使用该语法,不能使用es5的对象完整形式
     call(){
         console.log("我可以打电话");
     }
 }
 let onePlus=new Phone('1+',1999);
 console.log(onePlus);
 //Phone {brand: "1+", price: 1999}
 onePlus.call();
 //我可以打电话
16.1 class的静态成员

静态属性 属于类本身,而不属于它的实例对象,利用实例对象无法调用,当可以利用类本身调用。

class Phone{
    static name='手机';
    phone='华为';
    static change(){
        console.log('我可以改变世界');
    }
}
let nokia=new Phone();
console.log(Phone.name);
//手机
console.log(nokia.name);
//undefined
console.log(nokia.phone);
//华为
nokia.change();
//nokia.change is not a function
Phone.change();
//我可以改变世界
16.2 class继承

先来看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);     //利用原型链实现对父类型对象的方法继承,利用call()方法并借助父类型构造函数初始化相同属性
    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 phone=new smartPhone('华为',5499,'黑色','5.5inch');
console.log(phone);
//smartPhone {brand: "华为", price: 5499, color: "黑色", size: "5.5inch"}

ES6 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);   //Phone.call(this,brand,price)
        this.color=color;
        this.size=size;
    }
    photo(){
        console.log('我可以拍照');
    }
    playGame(){
        console.log('我可以打游戏');
    }

    call(){   //子类对父类方法的重写
        console.log('我可以进行视频通话');
    }
}

const phone=new smartPhone('小米',2499,'粉色','4.7inch');
console.log(phone);
//smartPhone {brand: "小米", price: 2499, color: "粉色", size: "4.7inch"}
phone.call();    //子类重写父类方法后,调用子类的重写方法,不在调用父类方法
//我可以进行视频通话
phone.photo();
//我可以拍照
phone.playGame();
//我可以打游戏
16.3 class中的get和set
class Phone {
       constructor(){
           this._price=null;
       }
       //get和set 不能和属性重名,一般以_区分
       get price() {        
           console.log('价格属性被读取了');
           // return 'iloveyou';
           return this._price;
       }
       set price(newVal){              
           console.log('价格属性被修改');
           this._price=newVal;
         
       }
   }

   //实例化对象 
   let s = new Phone();
   console.log(s.price);
   //价格属性被读取了
   //null
   s.price='free';
   console.log(s.price);
   //价格属性被修改
   //价格属性被读取了
   //free
17. ES6中的数值扩展
  1. Number.EPSILON 是JavaScript:表示的最小精度
// EPSILON 属性的值接近于2.2204460492503130808472633361816E-16
// 用在浮点数计算上,对精度进行设置的
console.log(0.1+0.2===0.3);
//false
function equal(a,b){
     if(Math.abs(a-b)<Number.EPSILON){
         return true;
     }else{
         return false;
     }         
 }
 console.log(equal(0.1+0.2,0.3));
 //true
  1. 二进制和八进制
 let b=0b1010;
 let o=0o777;
 let d=100;
 let x=0xff;
 console.log(b);
 //10
 console.log(o);
 //511
 console.log(d);
 //100
 console.log(x);
 //255
  1. Number.isFinite() 检测一个数值是否为有限数
console.log(Number.isFinite(100));
//true
console.log(Number.isFinite(100/0));
//false
console.log(Number.isFinite(Infinity));  //无穷
//false
  1. Number.isNaN() 检测一个数值是否为NaN
console.log(Number.isNaN(123));
//false
  1. Number.parseInt() 字符串转整数,Number.parseFloat() 字符串转浮点型
console.log(Number.parseInt('5211314love'));
//5211314
console.log(Number.parseFloat('3.1415926上神奇'));
//3.1415926
  1. Number.isInteger() 判断一个数是否为整数
console.log(Number.isInteger(5));
//true
console.log(Number.isInteger(2.5));
//false
  1. Math.trunc() 将数字的小数部分抹掉
console.log(Math.trunc(3.5));
//3
  1. Math.sign() 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100));
//1
console.log(Math.sign(0));
//0
console.log(Math.sign(-20000));
//-1
18. 对象方法扩展
  1. Object.is()判断两个值是否完全相等
console.log(Object.is(120, 120)); //===
//true
console.log(Object.is(NaN, NaN));
//true
console.log(NaN === NaN); //我们知道NaN和任何数去作比较,除了不等于,其他结果都为false
//false
  1. Object.assign()对象的合并 ,如果对象中有相同的属性,后边的会覆盖掉前边的,如果不重复,则都保留
const config1={
    host:'localhost',
    port:3306,
    name:'root',
    pass:'root',
    test:'test'
};
const config2={
    host:'https://baidu.com',
    port:33060,
    name:'admin',
    pass:'admin',
    test2:'test2'
}
console.log(Object.assign(config1,config2));
//{host: "https://baidu.com", port: 33060, name: "admin", pass: "admin", test: "test","test2"}
  1. Object.setPrototypeOf() 设置原型对象 Object.getPrototypeof()获取
const compony={
    name:'腾讯'
}
const cities={
    address:['北京','上海','深圳']
}
Object.setPrototypeOf(compony,cities);   //cities作为compony的原型对象
console.log(Object.getPrototypeOf(compony));
//{address: Array(3)}=>  address: (3) ["北京", "上海", "深圳"]
console.log(Object.getPrototypeOf(cities));
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
console.log(compony);
//{name: "腾讯"}
19. ES6模块化
 // 模块化  : 是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
 // 模块化的好处: 1)防止命名冲突   2)代码重用   3)高维护性
 // ES6之前的模块化规范有:
 // CommonJS  =>NodeJS,Browserify
 // AMD   =>requireJS
 // CMD   => seaJS


 // ES6模块化语法
 // 模块功能主要由两个命令构成 :export  和  import
 // export 命令用于规定模块的对外接口
 // import 命令用于输入其他模块提供的功能

 // 分别暴露 ,统一暴露,默认暴露
20. 装饰器

详细介绍请点击这篇文章查看:
ES6中装饰器的简单介绍

ES7 新特性

1. includes()

该方法用来判断是否存在其中,类比indexof方法。

const mingzhu=['西游记','红楼梦','三国演义','水浒传'];

// 判断
console.log(mingzhu.includes('西游记'));
//true
console.log(mingzhu.includes('钢铁是怎么样练成的'));
//false
2. 幂运算(**)
  console.log(2 ** 10); //ES7幂运算
  //1024
  console.log(Math.pow(2, 10));//math函数幂运算
  //1024

ES8 新特性

1. async和await

两种语法结合可以让异步代码像同步代码一样
async 函数 :

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

await表达式 :

  • await 必须写在async函数中
  • await右侧的表达式一般为promise对象
  • await返回的是promise成功的值
  • await的promise失败了,就会抛出异常,需要通过try…catch 捕获处理
async function fn(){
     // return '好好学习';
     // 如果返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise对象
     // return;
     // 抛出错误,返回的结果是一个失败的Promise
     // throw new Error('出错了');
     // 返回的结果如果是一个Promise对象
     return new Promise((resolve,reject)=>{
         resolve('成功的数据');
         //reject('失败的值');
     });
 }
 const result=fn();
 // console.log(result);
 result.then(value=>{
     console.log(value);
     //成功的数据
 },reason=>{
     console.log(reason);
     //失败的数据
 })
const p= new Promise((resolve,reject)=>{
    resolve("用户数据");
})
// await 要放到async函数中
async function main(){
    try{   
     let result= await p;
     console.log(result);
     //用户数据
    }
    catch(e){
        console.log(e);
    }
}
main();
2. 新增对象方法
// 声明对象 
 const compony={
     name:'阿里',
     cities:['北京','上海','深圳'],
     gangwei:['前端','Java','大数据','运维']
 };
// 获取对象所有的键
console.log(Object.keys(compony));
// 获取对象所有的值
console.log(Object.values(compony));
// entries
console.log(Object.entries(compony));  // =>返回的是一个数组,而每个成员又是一个数组。 方便创建一个map

在这里插入图片描述

console.log(Object.getOwnPropertyDescriptors(compony));   //创建对象时属性描述对象的一种形式
const obj=Object.create(null,{
    name:{
        //设置值
        value:'好好学习',
        //属性特性
        writable:true,
        configurable:true,
        enumerable:true

    }
})

在这里插入图片描述

ES9 新增特性

1. ES9中的对象展开
// Rest 参数与spread扩展运算符在ES6中已经引入,不过ES6中只针对于数组,在ES9中为对象提供了像数组一样的 rest参数和扩展运算符
function connect({host,port,...user}){
         console.log(host);
         //127.0.0.1 
         console.log(port);
         //3306
         console.log(user);
         //{username: "root", password: "root", type: "master"
     }
     connect({
         host:'127.0.0.1',
         port:3306,
         username:'root',
         password:'root',
         type:'master'
     });
;