es6简介:
- ECMAScript是javascript标准, ES6就是ECMAScript的第6个版本
- ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
1. let:
let 用来声明变量, let就是限制在{}中的var, 只能在代码块内有效, 在花括号外是无法访问到内部的变量
var 声明的变量会被提升, 而let不会被提升, 主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
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 {
}