ES6基础

135 阅读7分钟

es6简介:

  • ECMAScript是javascript标准, ES6就是ECMAScript的第6个版本
  • ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

1. let:

let 用来声明变量, let就是限制在{}中的var, 只能在代码块内有效, 在花括号外是无法访问到内部的变量

image.png

var 声明的变量会被提升, 而let不会被提升, 主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

image.png

let 不允许在相同作用域内,重复声明同一个变量。
// let不能重新赋值
let sum = 10
let sum = 20 // false

// 不在同一个作用域内可以重新声明
let num = 10 
function func() {
    let num = 20
    console.log(num); // 输出20
} func()
console.log(num); // 输出10

// var可以重新赋值
var s = 10
var s = 20 // true

2.const

用来声明一个常量
const a = 100

// 1 一定要赋初始值
const A // 报错
// 2 常量的值不能修改
const a = 10 // err
// 也是块级作用域
{
    const sum = 10
}
console.log(sum) // 无法访问

// 假如是对数组和对象的元素修改, 不做对常量修改, 不会报错
const arr = [1, 2, 'hello']
arr.push('world')
console.log(arr) // [1, 2, 'hello', 'world']

3.解构

按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
let [a, b, c] = [1, 2, 3];
如果解构不成功,变量的值就等于`undefined`
let [foo] = [];
let [bar, foo] = [1];
对象的解构
const obj = {
    name: 'gau',
    age: 18,
    func: function() {
        console.log('我会敲代码');
    }
}
let {name, age, func} = obj

4.模板字符串

1. 声明
let str = `我是一个模板字符串`

2. 内容中可以直接出现换行符
let str = `
    <ul>
        <li>张三</li>
        <li>李四</li>
    </ul>
`
console.log(str);
3. 拼接
let strF = 'hello'
let str = `${strF} world!`
console.log(str); // hello world!

5.简化对象写法

es6允许在大括号里面直接写入变量和函数, 作为对象的属性和方法
let name= '张三'
let change = function() {
    console.log('我可以敲代码')
}

const men = {
    name,
    change,
}

6.箭头函数

 1. this是静态的, this 始终指向函数声明时所在的作用域下的this的值
 
function getName() {
    console.log(this.name);
}
let postName = () => {
    console.log(this.name);
}

window.name = '张三'
const setName = {
    name: '李四'
}
getName() // 张三
postName() // 张三

getName.call(setName) // 李四
postName.call(setName) // 张三
2. 不能作为构造实例化对象
let Person = (name, age) => {
    this.name = name
    this.age = age
}

let my = new Person('张三', 18)
console.log(my) // Person is not a constructor
3. 不能使用arguments变量
let arg = () => {
    console.log(arguments);
}
arg(1, 2, 3) // err
4. 箭头函数简写方式
// 当只有一个形参可以不加括号, 执行语句只有一句的话可以省略花括号
let func = n => console.log(n);

func('我是简写方式')

7.参数默认值

es6允许给函数参数赋值初始值
形参初始值 具有默认值的参数, 一般位置要靠后
//如果不给c传参他默认就是10, 如果传了就以传入得值计算, 如果不赋值也不传参就是undefined
function add(a, b, c = 10) {
    return a + b + c
}
add(1, 2, 3?)

8.rest参数

function data(...args) {
    console.log(args)
}
data(1, 2, 3) // [1, 2, 3]

//rest 参数必须放到最后
function data(a, b, ...args) {
    console.log(args)
}
data(1, 2, 3, 4, 5) // 1 2 [3, 4, 5]

9.扩展运算符

拓展运算符啃咬将数组转换成逗号分隔的参数序列
const n = ['1', 2, '张三']
console.log(...n); // 1, 2, 张三

// 可以进行数组合并
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
const arr = [...arr1, ...arr2] // [1, 2, 3, 4, 5, 6]

// 数组克隆
const a = [1, 2, 3]
const b = [...a] // b = [1, 2, 3] 这里是浅拷贝

// 将伪数组转换成数组
const divs = document.querySelectorAll('div')
const dirAll = [...divs] // [div, div, div...]

10.Symbol基本使用

symbol是一种原始数据类型, 表示独一无二的值, 他是js的第七种数据类型, 其他的类型是: `undefined``null`、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。
特点:
1. 值是唯一的, 可以用来解决命名冲突的问题
2. 不能与其他数据类型进行运算
3. 定义的对象不能for..in循环遍历, 但是可以用Reflect.ownKeys来获取对象的所有的键名
// 创建一个Symbol 方法一
let s = Symbol()

let s2 = Symbol('张三')
let s3 = Symbol('张三')
s2 === s3 // false

Symbol.for 创建 方法二
let s4 = Symbol.for('李四')
let s5 = Symbol.for('李四')
s4 === s5 // true

11.Set集合

Set: 它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成 Set 数据结构。
// 声明一个 set
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
}

// 去除数组的重复成员
[...new Set(array)]

// 去除字符串里面的重复字符。
[...new Set('ababbc')].join('')
// "abc"

// set的四种操作方法:
`Set.prototype.add(value)`:添加某个值,返回 Set 结构本身。
`Set.prototype.delete(value)`:删除某个值,返回一个布尔值,表示删除是否成功。
`Set.prototype.has(value)`:返回一个布尔值,表示该值是否为`Set`的成员。
`Set.prototype.clear()`:清除所有成员,没有返回值。

12.迭代器

迭代器是一种接口, 为不同数据结构提供统一的访问机制
任何数据类型结构只要部署了iterator, 就可以完成遍历操作
1. es6创建了一种新的遍历命令for...of, iterator接口主要提供for...of消费
2. 原生具备iterator接口的数据(可以for...of遍历)
array, arguments, set, map, string, typedArray, nodeList
3. 工作原理
创建一个指针对象,指向当前数据类型的起始位置
第一次调用next方法,指针自动指向数据结构第一个成员, 接下来会一直往后移直到最后一个
// 创建一个数组
const xiyou = ['唐僧', '悟空', '八戒', '沙僧']
// 使用 for of 遍历数组
for(let v of xiyou) {
    console.log(v) // 唐僧, 悟空, 八戒, 沙僧
}
let interator = xiyou[Symbol.iterator]()
interator.next() //指向唐僧
interator.next() //指向悟空
interator.next() //指向八戒
interator.next() //指向沙僧
interator.next() //{value: undefined, done: true} 表示完成

13.生成器

生成器其实就是一个特殊的函数
异步编程  纯回调函数  node fs ajax mongodb
// 如何声明
function * gen() {
    console.log('hello world')
}
// 如何执行
let iterator = gen()
iterator.next()

function * pos() {
    yield'张三'
    console.log('hello world')
    yield'李四'
    console.log('hello js')
    yield'王五'
    console.log('hello es6')
}
// 如何执行
let iterator = pos()
// 链式解构 依次打印
console.log(iterator.next()) // 张三
console.log(iterator.next()) // 李四
console.log(iterator.next()) // 王五
console.log(iterator.next()) {value: undefined, done: true} 表示已经执行完

// 案例
function one() {
    setTimeout(() => {
        console.log('1');
        iterator.next() // 如果不加下面代码就不会执行
    }, 1000);
}
function two() {
    setTimeout(() => {
        console.log('2');
        iterator.next()
    }, 2000);
}
function three() {
    setTimeout(() => {
        console.log('3');
        iterator.next()
    }, 3000);
}

// 生成器里的代码以链式的形式存在
function * gen() {
    yield one();
    yield two();
    yield three();
}
let iterator = gen()
iterator.next()

14.Promise

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
所谓`Promise`,简单说就是一个容器(对象),里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
1. 基本用法:
ES6 规定,`Promise`对象是一个构造函数,用来生成`Promise`实例。
// 实例化 Promise 对象
const p = new Promise(function (resolve, reject) {
    setTimeout(() => {
        let data = '读取数据成功'
        resolve(data)
        let err = '数据读取失败'
        reject(err)
    }, 1000);
})
// 调用promise对象的then的方法
p.then(function (value) {
    // 请求成功则执行第一个回调
    console.log(value);
}, function (reason) {
    // 请求失败则执行第二个回调
    console.error(reason);
})
Promise读取文件
// 1.引入 fs 模块
const fs = require('fs')
fs.readFile('./data/古诗.md', (err, data) => {
    if(err) throw err;
    console.log(data.toString());
})

// 2. 使用Promise封装
const p = new Promise((resolve, reject) => {
    fs.readFile("./data/古诗.md", (err, data) => {
        //判断如果失败
        if(err) reject(err)
        //如果成功
        resolve(data.toString())
    })
})

p.then((value) => {
    console.log(value);
}, (reason) => {
    console.log('读取失败!', reason);
})
Promise封装ajax请求
// 接口地址: https://movie.douban.com/subject/26654184/?from=showing

// 1. 创建对象
const p = new Promise((resolve, reJect) => {
    const xhr = new XMLHttpRequest();
    // 2. 初始化
    xhr.open('GET', 'https://www.lz13.cn/mingrenmingyan/184174.html', true)
    // 3. 发送
    xhr.send()
    // 4.绑定事件, 处理响应结果
    xhr.onreadystatechange = () => {
        // 判断
        if (xhr.readyState === 4) {
            // 判断响应码 200 -299 区间
            if (xhr.status >= 200 && xhr.status < 300) {
                //表示成功
                resolve(xhr.response);
            } else {
                //如果失败
                reJect(xhr.status);
            }
        }
    }
})
p.then((value) => {
    console.log(value);
}, (reason) => {
    console.error('读取失败!', reason);
})

15.Map

map数据结构, 它类似于数组, 也是键值对的集合, 但是'键'的范围不限于字符串, 各类型的接口值(包括对象)都可以作为键.
// 声明 Map
let m = new Map()
// 添加元素
m.set('name', 张三)
m.set('change', function(){
    console.log('我会吃饭')
})

// size 
console.log(m.size)
// 删除
m.delete('name')
// 获取 
console.log(m.get('change'))
// clear 清空
m.clear() 
//遍历
for(let v of m) {
    console.log(v)
}

16.calss类

ES6 的`class`可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的`class`写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
class Point {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
    toString() {
      return '(' + this.x + ', ' + this.y + ')';
    }
  }
静态方法
如果在一个方法前,加上`static`关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo {
    static classMethod() {
      return 'hello';
    }
  }
  Foo.classMethod() // 'hello'
  var foo = new Foo();
  foo.classMethod()
  // TypeError: foo.classMethod is not a function
类的继承(通过extends)
class Point {
}
class ColorPoint extends Point {
}