EcmaScript(ES)
# ES
# 简介
ES 全称 EcmaScript,是脚本语言的规范,而平时经常编写的 JavaScript 是 Ecmascript 的一种实现,所以ES 新特性其实指的就是 JavaScript 的新特。
ECMA:European Computer Manufacturers Association 欧洲计算机制造商协会,这个组织的目的是评估、开发和认可电信和计算机标准。
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。2015年第6版:ES6
兼容性: http://kangax.github.io/compat-table/es6/
学习视频: https://www.bilibili.com/video/BV1uK411H7on
# let
let a;
let a,b,c,d;
let f = 100, g = 'zqc', h = [];
2
3
4
特性:
- 不能重复声明,但var可以重复声明;
- 块级作用域,代码块外读取不到;
- 不存在变量提升,不允许在变量声明之前使用。但var是可以在变量声明之前使用,
console.log(a)
输出为undefined
; - 不影响作用域链,块里面可以获取块外面的值
经典案例: https://www.bilibili.com/video/BV1uK411H7on?p=4
# const
const NAME = 'zqc';
注意点:
- 一定要赋初始值
- 一般要用大写
- 常量值不能修改
- 块级作用域
- 对于数组和对象的元素修改,不算做对常量的修改,不会报错。常量指向的地址没有改变
# 变量解构赋值
数组的解构
const F4 = ['1', '2', '3', '4']
let[a, b, c, d] = F4;
2
对象的解构
const zhao = {
name : 'zqc',
age: '25',
eat: function() {
console.log("eat")
}
};
let {name, age, eat} = zhao;
2
3
4
5
6
7
8
9
# 模版字符串
let str = `字符串`;
let a = `邹曲宸`;
let b = `${a}是我自己`;
2
3
特性:
- 内容中可以直接出现换行符
- 变量拼接
# 简化对象写法
let name = 'zqc';
let change = function() {
console.log('xxxxx');
}
const SCHOOL = {
name, // name: name
change, // change: change
improve() { // function可以不写
console.log('xx');
}
}
2
3
4
5
6
7
8
9
10
11
12
# 箭头函数
let fn = function(a,b) {
}
// 等价于
let fun = (a,b) => {
console.log(a + b);
}
fun(1,2)
2
3
4
5
6
7
8
9
function getName() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
window.name = 'zqc';
const N = {
name: 'zqc2'
}
// 直接调用
getName(); //zqc
getName2(); //zqc
// call 方法调用
getName.call(N); //zqc2
getName2.call(N); //zqc
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
特性:
- this是静态的,this始终指向声明函数时所在作用域下的 this 的值
- 不能作为构造实器例化对象
- 不能使用 arguments 变量
- 肩头函数的简写
- 省略小括号,当形参有且只有一个时
- 省略花括号,当代码只有一条语句时,return也有省略,执行结构就是函数返回值
let pow = n => n * n
案例: https://www.bilibili.com/video/BV1uK411H7on?p=10
# 函数参数默认值
function add(a, b, c=10) {
return a + b + c;
}
let result = add(1,2,3);
let result2 = add(1,2);
2
3
4
5
6
function connect({host="127.0.0.1",username,password,port}) {
...
}
connect({
host: 'localhost',
username: 'root',
password: 'root',
port: 3306
})
2
3
4
5
6
7
8
9
10
特性:
- 默认值的参数,位置一般要靠后。
- 解构赋值结合,没传的话就用默认值
# rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
function date(){
console.log(arguments);
}
date('a', 'b', 'c', 'd')
2
3
4
function date(...args) {
console.log(args)
}
date('a','b','c','d')
2
3
4
# 扩展运算符
扩展运算符能将数组转换为逗号分隔的参数序列
const arr = ['a', 'b', 'c'];
function fun(){
console.log(arguments)
}
fun(arr)
2
3
4
5
6
7
const arr = ['a', 'b', 'c'];
function fun(){
console.log(arguments)
}
fun(...arr)
2
3
4
5
6
7
应用: https://www.bilibili.com/video/BV1uK411H7on?p=14
数组合并
const A = ['a', 'b'];
const B = ['c', 'd'];
const C = [...A, ...B]; // 合并A和B
2
3
4
数组克隆
const A = ['a', 'b'];
const B = [...A];
2
将伪数组转换为真正的数组
const = document.querySelectorAll('div');
const divArr = [...divs];
2
# Symbol
ES6 引入的新的原始数据类型 Symbol,表示独一无二的值。
- Symbol 的值是唯一的,用来解决命名冲突的问题;
- Symbol 值不能与其他数据进行运算;
- Symbol 定义的对象属性不能使用 for...in 循环遍历,但可以使用 Reflect.ownKeys 来获取对象的所有键名。
let s = Symbol();
console.log(s, typeof s);
let s2 = Symbol('zqc');
let s3 = Symbol('zqc');
let s4 = Symbol.for('zqc');
2
3
4
5
七大数据类型 USONB: you are so niubilility
- u: undefined
- s: string symbol
- o: object
- n: null number
- b: boolean
let game = {}
let methods = {
up: Symbol('up'),
down: Symbol('down')
}
game[methods.up] = function() {
console.log("up");
}
game[methods.down] = function() {
console.log("down")
}
console.log(game)
2
3
4
5
6
7
8
9
10
11
12
13
let test = {
name: "playGame",
[Symbol('say')]: function(){
console.log("say")
},
[Symbol('down')]: function(){
console.log("down")
}
}
console.log(test)
2
3
4
5
6
7
8
9
10
11
Symbol内置属性,指向语言内部使用的方法
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("Person类型检查了")
}
}
let o = {}
console.log('Person', o instanceof Person);
2
3
4
5
6
7
8
const arr = [1,2,3]
const arr2 = [4,5,6]
console.log(arr.concat(arr2))
arr2[Symbol.isConcatSpreadable] = false
console.log(arr.concat(arr2))
2
3
4
5
# 迭代器
Iterator就是对象里面的一个属性。
Array, Arguments, Set, Map, String, TypedArray, NodeList
工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置;
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最好一个成员;
- 每调用 next 方法返回一个包含 value 和 done 属性的对象。
const arr = [1,2,3,4,5]
for(let v of arr) {
console.log(v)
}
console.log(arr)
let iterator = arr[Symbol.iterator]();
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
2
3
4
5
6
7
8
9
自定义迭代器
const banji = {
name: "Super One",
stus: [
'James',
'Tom',
'Jerry'
],
[Symbol.iterator](){
let index = 0;
let _this = this;
return {
next: function() {
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)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 生成器函数
生成器其实就是一个特殊的函数,进行异步编程。
function * gen() {
console.log("hello generator")
}
let iterator = gen()
console.log(iterator)
iterator.next()
2
3
4
5
6
7
function * gen() {
console.log(1111)
yield 1
console.log(2222)
yield 2
console.log(3333)
yield 3
console.log(4444)
}
let iterator = gen()
iterator.next()
iterator.next()
iterator.next()
iterator.next()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
console.log(1111)
yield 1
console.log(2222)
yield 2
console.log(3333)
yield 3
console.log(4444)
}
for(let v of gen()) {
console.log(v)
}
2
3
4
5
6
7
8
9
10
11
next也可以传参
function * gen(arg) {
console.log(arg)
let one = yield 1
console.log(one)
let two = yield 2
console.log(two)
yield 3
}
let iter = gen('AAA');
console.log(iter.next());
console.log(iter.next('BBBB'));
console.log(iter.next('CCCC'));
2
3
4
5
6
7
8
9
10
11
12
控制台定时输出:
// 定时器 如果太多的情况,回调地狱
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 1000)
}, 1000)
}, 1000)
// 生成器函数
function one() {
setTimeout(()=>{
console.log(1)
iter.next()
},1000)
}
function two() {
setTimeout(()=>{
console.log(2)
iter.next()
},1000)
}
function three() {
setTimeout(()=>{
console.log(3)
},1000)
}
function * gen() {
yield one();
yield two();
yield three();
}
let iter = gen();
iter.next()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Promise
异步编程的新解决方案。Promise是一个构造函数,用来封装一步操作并可以获取其成功或失败的结果。
// 实例化 Promise 对象;
const p = new Promise(function(resolve, reject){
setTimeout(function() {
let data = "data from DB";
//resolve(data);
reject(data);
}, 1000)
});
// 调用 Promise 对象的 then 方法
p.then(
// 成功调用
function(value) {
console.log(value);
},
// 失败调用
function(reason){
console.error(reason)
}
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Promise 读取文件
// 1. 引入 fs 模块
const fs = require('fs')
// 2. 调用方法读取文件
fs.readFile('./为学2.md', (err, data) => {
if(err) throw err; // 如果失败抛出异常
console.log(data.toString())
});
// 3. 使用Promise 封装
const p = new Promise(function(resolve, reject){
fs.readFile('./为学2.md', (err, data) => {
if(err) reject(err)
resolve(data);
});
});
p.then(
function(value){
console.log(value.toString());
},
function(reason){
console.log('读取失败');
}
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26