ES6学习笔记

205 阅读9分钟

1. let,const关键字

let

作用

  • 与var类似,用于声明一个变量

特点

  • 在块作用域内有效
  • 不能重复声明
  • 不会预处理,不存在提升

应用

  • 循环遍历加监听
  • 使用let取代var是趋势

const

作用

  • 定义一个常量

特点

  • 不能修改
  • 其它特点同let

应用

  • 保存不用改变的数据

2. 变量的解构赋值

  • 从对象或数组中提取数据,并赋值给变量(多个)
  • 对象的解构赋值
<script>
let obj = {username:'kobe',age:39}
let {username,age} = obj //相当于全局定义了username,age
console.log(username,age)
</script>
  • 数组的解构赋值
<script>
let arr = [1,3,5,'abc',true]
let [,,a,b] = arr
console.log(a,b) //5,'abc'
</script>

3. 模板字符串

简化字符串的拼接

变化的部分使用${xxx}定义

<script>
let obj = {username:'kobe',age:39};
let str = `我的名字叫:${obj.username},我今年的年龄是:${obj.age}`;
console.log(str)
</script>

4. 对象的简写方式

  • 省略同名的属性名

  • 省略方法的function

<script>
let username = 'kobe';
let age = 39;
let obj = {
    username,  //同名的属性可以省略不写,等价于username:username
    age,
    getName(){  //可以省略函数的function, 等价于getName: function(){}
        return this.username;
    }
}
console.log(obj.getName())
</script>

5. 箭头函数

作用:定义匿名函数

特点:

  • 简洁
  • 箭头函数没有自己的this,箭头函数的this不是调用的使用决定的,而是在定义的时候决定的,而在定义的时候处在的对象就是它的this
  • 扩展理解:箭头函数的this看外层的是否有函数, 如果有,外层函数的this就是内部函数的this, 如果没有,则this是window
<script>
形参的情况
1.没有形参的时候
let fun1 = () => console.log('我是箭头函数')
fun1();
2.只有一个形参的时候()可以省略
let fun2 = a => console.log(a);
fun2('aaa');
3.两个及两个以上形参的时候()不能省略
let fun3 = (x,y) => console.log(x,y);
fun3(23,34);

函数体的情况
1.函数体只有一条语句或者是表达式的时候{}可以省略--->会自动返回语句执行的结果或者表达式的结果
let fun = (x,y) => x + y;    //等价于{return x + y }
console.log(fun(2,5))
2.函数体不止一条语句或表达式的时候{}不可以省略,必须return返回的结果
let fun = (x,y) => {
    console.log(x+y);
    return x + y;
}
console.log(fun(2,4));
</script>

6.三点运算符

用途

1.rest(可变)参数,用来取代arguments,但比arguments灵活,只能是最后部分形参参数

function fun(a,...value) {
    console.log(value) //1,2,3
    value.forEach(function (item,index){
        console.log(item,index)
    })
};
fun(7,1,2,3);

2.扩展运算符(默认调用iterator接口)

let arr = [1,6];
let arr1 = [2,3,4,5];
arr = [1,...arr1,6];
console.log(arr); //[1,2,3,4,5,6]
conosle.log(...arr); //1,2,3,4,5,6

7. 形参默认值

当不传入参数的时候默认使用形参的默认值

function Point(x=1,y=2){
    this.x = x;
    this.y = y;
}
let point1 = new Point();
console.log(point1);

8.promise对象

1. 理解

  • Promise对象:代表了未来某个将要发生的事件(通常是一个异步操作)
  • 有了promise对象,可以将异步操作以同步的流程表达出来,避免了层层嵌套的回调函数(俗称'回调地狱')
  • ES6的Promise是一个构造函数,用来生成promise实例

2. 使用promise基本步骤(2步)

1. 创建promise对象
let promise = new Promise((resolve,reject)=>{
    //初始化promise状态为pending
    //执行异步操作
    if(异步操作成功){
        resolve(value);//修改promise的状态为fullfilled
    }else{
        reject(errMsg);//修该promise的状态为rejected
    }
})
2. 调用promise的then()
promise.then(function(
    result => console.log(result),
    errorMsg => alert(errorMsg)
))

3.promise对象的3个状态

  • pending:初始化状态
  • fullfilled:成功状态
  • rejected:失败状态

4.应用

  • 使用promise实现超时处理
  • 使用promise封装处理ajax请求

9. Symbol属性介绍

1. 概念

  • ES6中添加了一种原始数据类型symbol(已有的原始数据类型:String,Number,boolean,null,undefined,Object)

2. 特点

  • Symbol属性值对应的值是唯一的,解决命名冲突问题
  • Symbol值不能与其他数据进行计算,包括同字符串拼串
  • for in,for of遍历时不会遍历symbol属性

3. 使用

  • 调用Symbol函数得到symmbol值
let symbol = Symbol();
let obj = {};
obj[symbol] = 'hello';
console.log(obj)
  • 传参标识
let symbol = Symbol('one');
let symbol2 = Symbol('two');
console.log(symbol);
console.log(symbol2);
  • 内置Symbol值

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

Symbol.iterator,对象的Symbol.iterator属性,指向该对象的默认遍历器方法

10.iterator接口机制

概念:

  • iterator是一种接口机制,为各种不同数据结构提供统一的返回机制

作用:

  • 为各种数据结构,提供一个统一的、简便的访问接口
  • 使得数据结构的成员能够按某种次序排列
  • ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费

原理:

  • 创建一个指针对象(遍历器对象),指向数据结构的起始位置。
  • 第一次调用next方法,指针自动指向数据结构的第一个成员,接下来不断调用next方法,指针会一直向后移动,直到指向最后一个成员。
  • 每调用next方法返回一个包含value和done的对象(value:当前成员的值,done:布尔值,表示当前的数据结构是否遍历结束),当遍历结束的时候返回的value值是undefined,done值为true
  • 将iterator接口部署到指定的数据类型上(数组,字符串,arguments,set容器,map容器),可以使用for of去循环遍历,当使用for of去遍历目标数据的时候,该数据会自动去找Symbol.iterator属性

11.Generator函数

概念:

  • ES6提供的解决异步编程的方案之一
  • Generator函数是一个状态机,内部封装了不同状态的数据
  • 用来生成遍历器对象
  • 可暂停函数(惰性求值),yield可暂停,next方法可启动,每次返回的是yield后的表达式结果

特点

  • function与函数名之间有一个星号
  • 内部用yield表达式来定义不同的状态
  • generator函数返回的是指针对象,而不会执行函数内部逻辑
  • 调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{vaule:yield后的表达式结果/undefined,done}
  • 再次调用next方法会从上一次停止时yield处开始,直到最后
  • yield语句返回结果通常为undefined,当调用next方法是传参内容会作为启动时yield语句的返回值
function* myGenerator(){
    console.log('开始遍历');
    let result = yield 'hello';//undefined
    console.log(result)//qqq
    yield 'generator'
    console.log('遍历完毕')
    return '返回的结果'
}
let MG = myGenetator();//返回的是指针对象
console.log(MG);
console.log(MG.next());
console.log(MG.next('qqq'));
console.log(MG.next());

12. async函数(源于ES2017)

概念

  • 真正意义上去解决异步回调的问题,同步流程表达异步操作

本质

  • Generator的语法糖

特点

  • 不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就继续往下执行
  • 返回的总是Promise对象,可以用then方法进行下一步操作
  • async取代Generator函数的星号*,await取代Generator的yield
  • 语义上更为明确,使用简单
async function foo(){
    await 异步操作;
    await 异步操作;
}

13. class类的使用

  • 通过class定义类/实现类的继承
  • 在类中通过constructor定义构造方法
  • 通过new来创建类的实例
  • 通过extends来实现类的继承
  • 通过super调用父类的构造方法
  • 重写从父类中继承的一般方法
//定义一个人物的类
class Person {
    //类的构造方法
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    //类的一般方法
    showName(){
        console.log(this.name)
    }
}
let person = new Person('kobe',23);
console.log(person);
person.showName();
//子类
class StarPerson extends Person{
    constructor(name,age,salary){
        super(name,age);//调用父类的构造方法
        this.salary = salary;
    }
    //父类的方法重写
    showName(){
        console.log(this.name,this.age,this.salary)
    }
}
let p1 = new StarPerson('wade',36,100000);
console.log(p1);
p1.showName();

14. 字符串,数组的扩展

字符串扩展

  • includes(str): 判断是否包含指定的字符串
  • startsWith(str): 判断是否以指定字符串开头
  • endsWith(str): 判断是否以指定字符串结尾
  • repeat(count): 重复指定次数

数组扩展

  • 二进制与八进制数值表示法:二进制用0b,八进制用0o
  • Number.isFinite(i):判断是否是有限大的数
  • Number.isNaN(i):判断是否是NaN
  • Number.isInteger(i):判断是否是整数
  • Number.parseInt(str):将字符串转换为对应的数值
  • Math.trunc(i):直接去除小数部分

数组方法的扩展

  • Array.from(v):将伪数组对象或可遍历对象转换为真数组
  • Array.of(v1,v2,v3):将一系列值转换成数组
  • find(function(value,index,arr){return true}):找出第一个满足条件返回true的元素
  • findIndex(function(value,index,arr){return true}):找出第一个满足条件返回true的元素下标

对象方法的扩展

  • Object.is(v1,v2):判断2个数据是否完全相等(以字符串的形式判断)
console.log(Object.is(NaN,NaN))//true
console.log(Object.is(0,-0))//false
  • Object.assign(target,source1,source2...):将源对象的属性复制到目标对象上
let obj = {};
let obj1 = {username:'vad',age:23};
let obj2 = {sex:'男'};
Object.assign(obj,obj1,obj2);
console.log(obj);
  • 直接操作_proto_属性
let obj2 = {};
obj2._proto_ = obj1;

15. 深度克隆

基本数据类型:

拷贝后会生成一份新的数据,修改拷贝以后的数据不会影响原数据

对象/数组:

拷贝后不会生成新的数据,而是拷贝引用,修改拷贝以后的数据会影响原来的数据

拷贝数据的方法

  • 直接赋值给一个变量 //浅拷贝
  • Object.assign() //浅拷贝,将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象
  • Array.prototype.concat() //浅拷贝
  • Array.prototype.slice() //浅拷贝
  • JSON.parse(JSON.stringify()) //深拷贝,拷贝的数据里不能有函数
let obj = {username:'kova'};
let obj2 = Object.assign(obj);
console.log(obj2)

浅拷贝(对象/数组)

  • 特点:拷贝的引用,修改拷贝以后的数据会影响原数据

深拷贝

  • 拷贝的时候生成新数据,修改拷贝以后的数据不会影响原数据
//定义检测数据类型的功能函数
function checkedType(target){
    return Object.prototype.toString.call(target).slice(8,-1)
}
//实现深度克隆 ---> 对象/数组
function clone(target){
    //判断拷贝的数据类型
    //初始化变量result成为最终克隆的数据
    let result,targetType = checkedType(target);
    if(targerType === 'Object'){
        result = {};
    }else if (targetType === 'Array') {
        result = [];
    }else{
        result target;
    }
    //遍历目标数据
    for (let i in target){
        //获取遍历数据结构的每一项值
        let value = target[i];
        //判断目标结构里的每一项是否存在数组/对象
        if(checkedType(value)==='Object' || checkedType(value)==='Array'){
            //继续遍历获取到的value值
            result[i] = clone(value);
        }else{
            result[i]=value;
        }
    }
    return result;
}

16. set,map容器

Set容器

无序不可重复的多个value的集合体

  • Set()
  • Set(array)
  • add(value)
  • delete(value)
  • has(value)
  • clear()
  • size
let set = new Set([1,3,4,2,4,5]);
console.log(set);
set.add(7);
set.clear();

Map容器

无序的key不重复的多个key-vaule的集合体

  • Map()
  • Map(array)
  • set(key,value)
  • get(key)
  • delete(key)
  • has(key)
  • clear()
  • size
//传的是二维数组
let map = new Map([['aaa','username'],[35,'age']]);
console.log(map);
map.set(78,'jha');

17. ES7

指数运算符(幂):**

Array.prototype.includes(value):判断数组中是否包含指定的value

console.log(3 ** 3);
let arr = [1,2,4,'adg'];
console.log(arr.includes('a'); //false