ECMA:European Computer Manufacturers Association,欧洲计算机制造商协会。ECMA是一个国际标准化组织,致力于制定和推广信息和通信技术(ICT)标准,以促进全球计算机和通信技术的发展。 ECMA制定了许多标准,包括ECMAScript(JavaScript)和ECMA-262(JavaScript语言规范)等。
ES6
let变量
- let变量不能重复声明
- let变量可限制在块级作用域内有效
- let变量不能实现变量提升(let变量实际也有变量提升,但运行时会报错)
const常量
- const常量声明时即需要赋值
- const常量定义后不能再赋值,变更其引用
- const常量可限制在块级作用域内有效
解构赋值
- 数组解构赋值,
let [var1, var2, var3] = ['val1', 'val2', 'val3'] - 对象解构赋值,
const {filed1, filed2} = {field1: '', field2: ''}
模版字符串
- 使用````反引号包裹内容
- 内容中可以使用变量
${variable}
箭头函数
- 使用
()=>{}表示,()内是形式参数,{}是函数体 - 箭头函数没有
this,它的this是静态的,指向声明时所在作用域的this - 不能作为构造实例化对象
- 不能使用
arguments变量
扩展运算符
- 扩展运算符使用
...表示 - 扩展运算符可以将数组转为逗号分隔的参数序列,
...array
Symbol
在 ES5 中对象属性名都是字符串,这容易造成属性名的冲突,在修改添加新属性或方法时可能造成覆盖。因此为保证每个属性的名字都是独一无二,ES6 引入了 Symbol。
- Symbol 是原始数据类型,表示独一无二的值
- Symbol的值是唯一的
// 创建
let s = Symbol();
console.log(s); // Symbol()
// 创建Symbol可以添加描述
// 描述并不代表Symbol的实际值
// 描述只是为了方便区分
let s2 = Symbol('description');
let s3 = Symbol('description');
console.log(s2 === s3); // false
// 调用Symbol.for()可以创建并添加描述
let s4 = Symbol.for('description');
let s5 = Symbol.for('description');
console.log(s4 === s5); // true
// Symbol.prototype.description 可以获取描述
consoel.log(s2.description); // 'description'
将 Symbol 作为对象属性/方法名,这样就能避免属性/函数名冲突
// 对象
const obj = {}
// Symbol
let s = Symbol();
// Symbol作为属性名
obj[s] = 'value';
let name = Symbol();
const obj = {
name: 'name',
[name]: function() {
console.log('hello');
}
}
console.log(obj.name); // name
obj[name](); // hello
迭代器
具有Symbol.iterator属性(接口)的,可以使用for...of...遍历
const arr = [1, 2, 3];
let iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
生成器函数
生成器函数是一种异步编程的解决方案;
传统的异步函数是回调函数,而生成器函数则是另一种异步函数。
生成器函数使用function *表示。
// 生成器函数在调用时,不会立即执行,而是返回一个迭代器对象
// 当调用 next() 后才执行函数体内容
function * gen() {
console.log('hello');
}
let i = gen();
console.log(i); // gen {<suspended>}
i.next(); // hello
// 生成器函数中可以使用 yield 实现函数代码分割
// yield 可以是字面量,也可以是表达式
function * gen() {
console.log('segment1');
yield 'hello';
console.log('segment2');
yield 'world';
console.log('segment3');
}
let i = gen();
// 遍历时,会以 yield 作为分隔分段执行函数内容
// 遍历时,遍历返回值就是 yield 内容
for (let v of i) {
console.log(v);
}
/*
segment1
hello
segment2
world
segment3
*/
// 使用迭代器 next() 方法完成分段执行函数内容
// next()会返回 {value:, done:} 的内容
let i2 = gen();
i2.next(); // segment1
i2.next(); // segment2
i2.next(); // segment3
// 传统异步编程,回调嵌套
setTimeout(()=>{
console.log('start');
setTimeout(()=>{
console.log('process');
setTimeout(()=>{
console.log('end');
}, 3000);
}, 2000);
}, 1000);
// 生成器函数异步编程
function start() {
setTimeout(()=>{
console.log('start');
iterator.next();
}, 1000);
}
function process() {
setTimeout(()=>{
console.log('process');
iterator.next()
}, 2000);
}
function end() {
setTimeout(()=>{
console.log('end');
iterator.next();
}, 3000);
}
function * gen() {
yield start();
yield process();
yield end();
}
let iterator = gen();
iterator.next();
// 生成器函数在执行 next() 时,可以传递实参
// next(val) 传入的实际参数会作为最近一个 yield 的返回值
function start() {
setTimeout(()=>{
console.log('start');
let data = '0%';
iterator.next(data); // 传递 data = '0%'
}, 1000);
}
function process() {
setTimeout(()=>{
console.log('process');
let data = '50%';
iterator.next(data); // 传递 data = '50%'
}, 2000);
}
function end() {
setTimeout(()=>{
console.log('end');
let data = '100%';
iterator.next(data); // 传递 data = '100%'
}, 3000);
}
function * gen() {
let progress1 = yield start();
console.log(progress1); // '0%'
let progress2 = yield process();
console.log(progress2); // '50%'
let progress3 = yield end();
console.log(progress3); // '100%'
}
let iterator = gen();
iterator.next();
Promise
Promise是ES6中的一种新的异步编程解决方案,语法上它是一个构造函数;
Promise可以用来封装异步操作中成功或失败的返回结果。
// Promise() 构造方法中传入一个函数参数,其中执行异步操作
// 形参函数中分别接收两个函数 resolve,reject
// resovle 在成功时调用
// reject 在失败时调用
const p = new Promise(function(resovle, reject){});
// Promise.then()方法用于异步处理的成功或失败结果
// Promise.then()分别接收两个回调函数,第一个代表成功,第二代表失败
// 成功的回调函数接收一个参数 value,获取 resovle(value)的入参
// 失败的回调函数接收一个参数 reason, 获取 reject(reason)的入参
p.then(function success(value){}, function error(reason){});
// Promise.then()方法返回的是一个Promise对象,因此可以链式调用
p.then().then();
// Promise.then()可以只接收第一个回调函数,只处理成功时的回调
p.then(function (value){});
// Promise.catch()则可以单独作为处理失败时的回调
p.catch(function (reason){});
const p = new Promise(function (resolve, reject) {
setTimeout(()=>{
let data = '获取的数据';
resolve(data);
}, 1000);
});
p.then(function success(value) {
console.log(value);
}, function error(reason) {
console.log(reason);
})
模块化
模块化规范:
- CommonJS,规范实现有 NodeJS Browserify
- AMD,规范实现有 requireJS
- CMD,规范实现有 seaJS
模块化语法:
- export,规定模块对外的接口
- import,导入其他模块实现的功能
导入方式:
import *,通用导入import {xx, yy},解构赋值导入import {default as xx},export default内容解构赋值导入,必须使用asimport xx,简便导入,仅针对于export default内容
模块化示例
- 编写模块化JS内容
// 使用 export 标识对外开放的数据
export let variable = 'hello';
export function fn() {
console.log('world');
}
// 使用 export {} 统一暴露
export {variable, fn}
// 使用 export default {} 默认暴露
export default {
name: 'w',
fn() {}
}
- 引入模块化JS文件
<script type="module">
// 导入所有,别名为myjs,从my.js文件导入
import * as myjs from "./my.js";
console.log(myjs); // Module {Symbol(Symbol.toStringTag): 'Module'}
// export deafult 内容需要通过 default 访问
console.log(myjs.default.name);
</script>
- 在JS文件中引入模块化JS文件
import * as myjs from './my.js'
console.log(myjs);
- 引入模块化JS文件
<script src="./base.js" type="module">/<script>