avatar

目录
JavaScript-ES6学习笔记

ECMAScript

  • ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准

  • ECMAScript 是 JavaScript 语言的规范

  • JavaScript 是 ECMAScript 语言的实现

    • 具体实现要看浏览器的内核
  • ES2015 和 ES6 是一样的

Babel转码器

Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码

配置文件

Babel的配置文件是.babelrc,存放在项目的根目录下
presets字段设定转码规则

Code
1
2
3
4
{
"presets": [],
"plugins": []
}

let和const

let

  1. 变量提升
  2. 作用域
  3. 再同一个块级作用域,不能声明同名的变量
  4. 暂时性死区
    Code
    1
    2
    3
    4
    5
    6
    7
    var tmp = 123;
    if(true){
    // 通过let声明的变量会绑定当前块级区域
    // 只能先声明再使用
    tmp ="abc";
    let tmp;
    }

const

const声明的是一个不变的量,叫做常量
声明的同时,必须初始化,一旦声明则不允许修改,否则报错
其他的跟Let一样

注意:引用类型定义的是存放的地址,其里面的值是可以修改的

数组结构赋值

以前:

Code
1
2
3
let a = 1; let b = 2;
// 更好的写法:
let a = 1,b = 2;

ES6:可以从数组中提取值,按照对应位置,对变量赋值。

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let [x,y] = ["a","b"];  // x=a,y=b
let [x,y] = ["a"]; // x=a,y=undefined

let [foo, [[bar], baz]] = [1, [[2], 3]];
// foo = 1,bar = 2,baz = 3

let [ , , third] = ["foo", "bar", "baz"];
// third = "baz"

let [x, , y] = [1, 2, 3];
// x = 1,y = 3

let [head, ...tail] = [1, 2, 3, 4];
// head = 1,tail = [2, 3, 4]

let [x, y, ...z] = ['a'];
x = "a",y = undefined,z = []

如果结构不成功,变量值都会等于undefined

Code
1
2
let [foo] = [];
let [bar, foo] = [1];

另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功

Code
1
2
3
4
5
let [x, y] = [1, 2, 3];
// x = 1,y = 2

let [a, [b], d] = [1, [2, 3], 4];
// a = 1,b = 2,d = 4

默认值:

Code
1
2
3
4
5
let [foo = true] = [];      //  foo = true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
let [x = 1] = [null]; // x // null

上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

对象的默认值

Code
1
2
3
4
5
6
7
function ajax(url,{
type: "get"
}){
console.log(type)
}

ajax("baidu.com") // get

字符串的扩展

常用方法

includes(str) 返回布尔值,表示是否找到了参数字符串
startWith(str) 返回布尔值,表示参数字符串是否再源字符串的头部
endsWith(str) 返回布尔值,表示参数字符串是否再源字符串的尾部
repeat(n) 返回一个新字符串,表示将原字符串重重n次

模板字符串

以前

Code
1
2
let name = "jack";
console.log("hello" + name)

现在

Code
1
2
let name = "jack";
console.log(`hello ${name}`)

数值的扩展

ES6 将全局方法parseInt,parseFloat,isNaN,isFinite,isInteger
到挂在到了Number对象上,以后使用都将加上Number.的前缀

数组的扩展

  • Array.from() 将伪数组装换成真数组
    • 伪数组:首先是个对象,有length属性切部位0,必须是num类型的
  • Array.of() 创建一个数组
    • Array(3)是创建了一个length为3的数组,Array.of(3)是创建了一个数组值为[3]
  • find()
    • 找出第一个符合条件的成员
  • findIndex()
    • 找出第一个符号条件的索引值
  • includes(str)
    • 是否包含str
  • for…of
    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(let index of arr.keys()){
    console.log(index); // 拿到索引值
    }


    for(let item of arr.values()){
    console.log(item) // 拿到每一项
    }

    for(let [index,item] of arr.entries()){
    console.log(index,item); // 两者的结合
    }

函数的扩展

  1. 函数的默认值

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    以前:
    function fn(a,b){
    let a = a || "hello";
    let b = b || "world"
    }

    现在:
    function fn(a = "hello",b = "world"){

    }
  2. rest参数

    • 将将函数多余的参数转换为一个数组
      Code
      1
      2
      3
      4
      function num(...aa){
      console.log(aa) // [1,2,3]
      }
      num(1,2,3)
  3. 扩展运算符

    • 将一个数组/对象展开
    • 可以替换apply写法
      Code
      1
      2
      3
      4
      5
      6
      7
      8
      9
      let arr = [1,2,3,4]
      console.log(...arr) // 1 2 3 4

      function aa(x,y,z){
      console.log(x,y,z)
      }

      aa.apply(null,arr)
      aa(...arr)
  4. 箭头函数

    • 会把this指向当前的作用域,使用的是定义时的this,而不是使用时的this
    • 不能作为构造函数
    • 不能使用arguments,用…rest
    • 他的一个缺点是:在底下声明,在上面不能调用。没有变量提升

对象的扩展

  1. 属性的简洁表示法

    • 当属性名跟变量名一样时,可以简写
      Code
      1
      2
      3
      4
      let [aa,bb] = [11,22];
      let obj = {aa,bb};

      console.log(obj) // {aa: 11,bb: 22}
  2. getter和setter

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let aa = {

_age = 10,

get age() {
return this._age
}

set age(value) {
if(age < 0 || age > 120){
throw new Error("请输入正确的年龄");
}
this._age = value
}
}

aa.age = 20;
console.log(aa.age) //20
  1. 属性的便利
    • for…in
    • Object.keys() 返回一个对象的所有键名

导入对象和导出对象

  • import可以导入对象,用法:
    • import 变量接收名 from “包的名称 | 包的路劲”
    • import “包的名称 | 包的路劲”
  • 导出对象
    • export default {}
      • 一个模块中只能导出一次
      • 在一个模块中可以同时使用export default 和 export
    • export var title = “”
      • 只能用{}的方式来接收
      • 导出时什么名字接收时就用什么名字
      • 如果想换个名字接收则可以使用as关键字
        • import { title as tt } form “module”
      • 如果想用一个变量导出所有成员也可以使用as关键字
        • import * as all from “module”

面对对象

老的面对对象写法:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function Person(arg){
this.name = arg.name;
this.age = arg.age;
}


Person.prototype = {
sayHello(){
console.log(hello)
}
}
Person.info = 10;

let zz = new Person({
name: 'zz',
age: 20
})
zz.sayHello();
console.log(Person.info);

ES6写法:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Person {

constructor(arg){
this.name = arg.name;
this.age = arg.age;
}

sayHello(){
console.log(hello);
}

static info = 10
}
let zz = new Person({
name: "zz",
age: "20"
})
zz.sayHello();
console.log(Person.info);

两种写法的结果都是一样的,但是ES6的写法看起来会更加的舒服

ES6中的继承写法:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Person {
constructor(arg){
this.name = arg.name,
this.age = arg.age
}
sayHello(){
console.log("hello");
}
}


class Chinese extends Person {
constructor(arg){
super(...arg);
this.sex = arg.sex,
this.stature = arg.stature;
}
}

let zyt = new Chinese({
name: "zyt",
age: "21",
sex: "woman",
stature: "155"
})

ES6中的继承是通过extends关键字来实现
class 子类 extends 父类
继承了之后就必须调用super方法

Set和Map

SetMap主要的应用场景在于数组去重数据存储

集合

  • 集合是由一组无序且唯一(即不能重复)的项组成的,可以想象成集合是一个既没有重复元素,也没有顺序概念的数组

  • ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值

  • Set 本身是一个构造函数,用来生成 Set 数据结构

  • 这里说的Set其实就是我们所要讲到的集合,先来看下基础用法

Javascript
1
2
3
4
5
6
7
8
9
10
11
const s = new Set();

[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
console.log(i); // 2 3 5 4
}

// 去除数组的重复成员
let array = [1,2,1,4,5,3];
[...new Set(array)] // [1, 2, 4, 5, 3]

Set实例的属性和方法

Set的属性:

  • size: 返回集合所包含元素的数量

Set的方法:

  • add(value):像集合添加一个新的项

  • delete(value):从集合中移除一个值

  • has(value):如果值在集合中存在,返回true否则false

  • clear():移除集合里所有的项

  • keys():返回一个包含集合中所有键的数组

  • values():返回一个包含集合中所有值的数组

  • entries:返回一个包含集合中所有键值对的数组

字典

在数据结构还有一种结构叫做字典,它就是实现基于ES6中的Map类的结构

那么集合又和字典有什么区别呢:

  • 共同点:集合、字典可以存储不重复的值
  • 不同点:集合是以[值,值]的形式存储元素,字典是以[键,值]的形式存储

所以这一下让我们明白了,Map其实的主要用途也是用于存储数据的,相比于Object只提供“字符串—值”的对应,Map提供了“值—值”的对应。也就是说如果你需要“键值对”的数据结构,Map比Object更合适

下面来看一下基本使用:

Javascript
1
2
3
4
5
6
7
8
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

属性:

  • size:返回字典所包含的元素个数

方法:

  • set(key,val):向字典中添加新元素

  • get(key):通过键值找特定的数值并返回

  • has(key):如果键存在字典中返回true否职责false

  • clear():将这个字典中的所有元素删除

  • keys():将字典中包含的所有键名以数组形式返回

  • values():将字典中包含的所有数值以数组形式返回

Promise

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

具体用法:

  1. 这里是封装了一个readFile的方法
    Javascript
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    const _readFile = (path) => {
    return new Promise((resolve,reject)=>{
    fs.readFile(path,"utf8",(err,data)=>{
    if (err){
    throw new Error("请求未成功")
    }else {
    resolve(data);
    }
    })
    })
    }

    _readFile(contactsPath)
    .then((data)=>{
    console.log(data);
    })

Promise.all

Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
resolve('success')
})

let p3 = Promse.reject('失败')

Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})

Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})

Promise.race

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})

let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})

Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})

async和await

async function用来定义一个返回Async function对象的异步函数,异步函数是指通过事件循环异步执行的函数,他会通过一个隐式的Promise返回其结果,如果你再代码中使用了异步函数,就会发现他的语法和结构会更像是标准的同步函数

await操作符用于等待一个Promise对象,它只能再异步函数async function中使用

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function fun(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("first");
},2000)
})
}

function fun1(){
return new Promise((resolve,reject)=>{
resolve("second")
})
}


async function fun2(){
let result1 = await fun()
let result2 = await fun2()
}

fun2(); // first second

Fetch

Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。

Fetch不能跨域,第一个.then返回的是status和url等数据,要想拿到传输过来数据,第一个.thenreturn res.json()

  • 用法:
    Code
    1
    2
    3
    4
    5
    6
    7
    fetch('http://example.com/movies.json')
    .then(function(response) {
    return response.json();
    })
    .then(function(myJson) {
    console.log(myJson);
    });

ES6新语法

  • 赋值

    • 数组结构赋值
      • let a = 1,b = 2,c = 3;
      • ES6: let [a,b,c] = [1,2,3];
    • 对象的结构赋值
      • let {foo,bar} = {foo: “hello”,bar: “hi”}
        • 对象属性别名(如果有了别名,那么原来的明治就无效)
        • let {foo:abc,bar} = {foo: “hello”,bar: “h1”}
        • console.log(abc) // hello
        • console.log(foo) //undefined
    • 字符串的结构赋值
      • let [a,b,c,d,e] = “hello”;
      • 就跟let [a,b,c,d,e] = [‘h’,’e’,’l’,’l’,’o’];一样
  • 字符串扩展

    • 常用方法

      • includes(str,index)
        • 判断字符中是否包含指定的字符,放回Boolean
        • arguments1:匹配的字符串,arguments2:从第几个开始匹配
      • stratsWith(str)
        • 判断字符串是否以特定的字符串开始
      • endWith(str)
        • 判断字符串是否以特定的字符串结束
    • 模板字符串(反单引号)

      • str

        Code
        1
        2
        3
        let obj = {name:'zz',age:'19'}
        console.log(`my name is ${obj.name}`)
        console.log(`${obj.age} years old this year`)
  • 函数扩展

    • 参数默认值

      • function foo(param = “hello”){}
    • 参数结构赋值

      • function foo({uname,age}={uname:”zz”,age:20})
      • 调用是赋值是 foo({uanme:’zz’,age:10})
    • rest参数(…)

      • Code
        1
        2
        3
        4
        5
        function foo(a,b,...param){
        console.log(a,b,param);
        }
        foo(1,2,3,4,5)
        result: a = 1,b = 2,param = [3,4,5];
    • 扩展运算符(…)

      Code
      1
      2
      3
      4
      5
      6
      function foo(a,b,c,d,e){
      console.log(a+b+c+d+e);
      }
      let arr = [1,2,3,4,5]
      foo(...arr);
      result: 15
    • 箭头函数

        1. 箭头函数中的this取决于函数的定义,而不是调用
        1. 箭头函数不可以new
        1. 箭头函数不可以使用arguments获取参数列表,可以使用rest来代替
  • 类与继承

    • 以前写法:
    Code
    1
    2
    3
    4
    let Person = (name) => {
    this.name = name;
    }
    Person.prototype.showName = () => { console.log(this.name); }
    • 现在写法
    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Person {
    // 静态方法(只有通过类名来调用,不能用实例对象来调用)
    static showInfo(){
    console.log('hi');
    }

    // 构造函数
    constructor(name) {
    this.name = name;
    }

    showName(){
    console.log(this.name)
    }
    }
    • 继承写法
    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class now extends Person {
    constructor(name,color){
    super(name); // super调用父类
    this.color = color;
    }

    showColor(){
    console.log(this.color);
    }
    }
### queryString
+ queryString.parse(str);
    * parse方法的作用就是把字符串转换成对象
+ queryString.stringify(obj)
    * 作用就是把对象转换成字符串
  • request.method
    • 获取当前请求的方式
文章作者: 青空
文章链接: https://gitee.com/AIR-ZRB/blog/2020/02/17/JavaScript-ES6%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 青空
打赏
  • 微信
    微信
  • 支付寶
    支付寶