ES6
2018-12-26 本文已影响0人
黑色的五叶草
基础部分:
一、新的声明方法
支持块作用域
{
let a = 1;
}
console.log(a) //undefined
let
:不可重复声明、支持块级作用域,可先声明后赋值
const
:常量,声明时就要赋值
<button></button>
<button></button>
<button></button>
<p></p>
<p></p>
<p></p>
<script>
var buttons = document.querySelectorAll('button');
for (let i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
for (let i = 0; i < buttons.length; i++) {
// 外层点击时清除所有button的样式
buttons[i].className = '';
ps[i].className = ''
}
// 对点击的添加样式
this.className = 'active';
ps[i].className = 'active';
}
}
</script>
二、解构赋值:
1.两边的结构必须一样
2.赋值和解构同时完成
let [a,b]=[5,8];
let {a,b}={12,5};
- 数组解构,空位可以用占位符
let arr = [1, 2, 3]; let [a ,b] = arr; console.log(a, b); // 1 2 // 对空位占位 let [x, , z] = arr; console.log(x,z); // 1 3
- 对象解构,左右变量名必须对应
// 1.从对象中结构出left变量 let {forward, back} = {forward: 100, back: 200}; console.log(forward); //100 // 2.从对象中解构出left值,并赋给L变量 -> 避免覆盖Window下全局变量 let {left: L, right: M} = {left: 100, right: 200}; console.log(L); //100 // 3.多重解构 let {foo: [a, b]} = {foo: [10, 20], bar: 'bar'}; console.log(a, b); // 10 20
- 字符串解构
// 对字符串解构,会产生一个特殊的行为 let [c, d, e, f, g, h] = 'string'; console.log(c, d, e, f, g, h); // s t r i n g
三、块级作用域
是什么:相当于添加了一个语法块
{
}
替代闭包:let const关键字形成块级作用域替代匿名函数创建闭包
let aBtn=document.getElementsByTagName('input');
for(let i=0;i<aBtn.length;i++){
aBtn[i].onclick=function (){
alert(i);
};
四、函数:箭头函数和this
箭头函数形式:
1.如果有且仅有一个参数,()也可以不写
2.如果有且仅有一个语句并且是return,{}也可以不写
(n) => { return n+1 }
n => n+1
let arr=[12,8,37,26,9];
/*arr.sort(function (n1, n2){
return n1-n2;
});*/
arr.sort((n1, n2)=>n1-n2);
箭头函数的this始终指向原创建对象或函数
/*
let json = {
a: 12,
//this=>当前的环境
fn: function () {
alert(this.a);
}
}
json.fn();
*/
class Json {
constructor() {
console.log(this);
this.a = 12;
this.fn = () => {
console.log(this);
alert(this.a);
}
}
}
let json = new Json();
let oDate = new Date();
oDate.fn = json.fn;
oDate.fn();
this始终指向Json对象
五、扩展运算符 ...
参数展开、数组展开、对象展开
1. 参数展开
function show(a, b, ...c){
console.log(a, b, c);
}
show(12,5,4,8,19,27,36);
// 12 5 [4,8,19,27,36]
2. 数组展开
let arr1=[12,5,8];
function show(a,b,c){
alert(a+b+c);
}
show(...arr1); // 25
3. 对象展开
let json={a: 12, b: 5, c: 99};
let json2={
...json,
d: 999
};
console.log(json2);
4.数组合并
let arr1 = [1, 2, 3];
let arr2 = ['a', 'b'];
let arr3 = [...arr1, ...arr2];
console.log(arr3); // [1, 2, 3, "a", "b"]
六、原生对象扩展
- Array扩展:
map: 映射,一一对应。[68, 30, 60, 77, 22] -> [及格,不及格,及格,及格,不及格]
reduce: 缩减(求和、平均) n>1
filter: 过滤
forEach: 遍历 - 模板字符串:识别换行符与变量表达式解析
${表达式}
- JSON写法:
JSON.parse()
转换成JSON,JSON.stringify()
转换成对象 - 对象扩展:对象的属性名必须是字符串
var x = 'souse';
var obj = {
// 属性名表达式
[x]: 1
}
console.log(obj); // {souse: 1}
七、异步(详见笔记)
promise
async/await
八、面向对象:主要特征在于封装
ES5面向对象:
- 没有语言自身的统一的写法
- 以函数的形式去写对象(不区分类与构造函数)
ES6面向对象:
- class 类声明
- constructor 构造函数
- extends 继承
- super 父类/超类
面向对象:
// 声明类
class Person{
// 声明构造函数
constructor(name, age){
this.name=name;
this.age=age;
}
showName(){
alert(this.name);
}
showAge(){
alert(this.age);
}
}
let p = new Person('blue', 18);
p.showName();
p.showAge();
继承:
/**
* 继承
* 1.声明子类
* 2.extends 声明继承父类
* 3.super 取得父类属性
*/
class Worker extends Person {
constructor (name, age, job) {
// 取得父类的属性
super(name, job);
// 声明子类自身的属性
this.job = job;
}
// 声明子类自身的方法
showJob () {
alert(this.job);
}
}
let w = new Worker('blue', '18', '爱吹逼的小福将');
w.showName();
w.showAge();
w.showJob();
九、ES6模块
- 导出(export)
- 变量
export let a=12;
export const a=12;
- 一堆
let a,b,c=...;
export {a, b, c, ...};
- 导出函数
export function show(){
...
}
- 导出class
export class Person{
...
}
默认成员
export default
- 导入
- 引入所有成员
import * as mod1 from 'xxx';
- 引入default成员
import mod1 from 'xxx';
对应export default
部分引入
import {a,b as name2} from 'xxx';
对应export {a, b, c, ...};
- 只引入样式表
import 'xxx';
- 异步引入 import() 函数本身是一个 promise 异步操作,要用到await
let p = import("./mod1");
^
|
let p = await import("./mod1");
进阶部分:
一、Symbol
的使用:
属性私有化(数据保护):每次创建的Symbol('a')都是一个新的实例
如下例所示,希望_gender属性只读不可写。传入的第二个gender参数,只可以通过调用原型对象的方法查看
var Person = (function() {
// 声明一个私有变量
var _gender = '';
// 调用私有变量形成闭包
function P(name, gender) {
this.name = name;
//this.gender = gender;
_gender = gender;
}
P.prototype.getGender = function() {
return _gender;
}
return P;
})();
var p1 = new Person('莫涛', '男');
console.log(p1);
console.log(p1.getGender());
二、迭代(循环)
迭代语句循环迭代对象,具有迭代器的迭代对象能被循环,迭代协议规定了迭代器
- 迭代协议:规定了迭代与实现的逻辑
- 迭代器[Symbol.iterator]:本质是一个方法,具体迭代的实现逻辑。数组和类数组对象都有,对象没有
- 迭代对象:可迭代的对象——具有[Symbol.iterator]方法
- 迭代语句:
for...in
以原始插入的顺序迭代对象的可枚举属性
for...of
根据迭代对象的迭代器具体实现迭代对象数据
for of内部实现原理:1.首先添加迭代器方法,迭代器定一个a(value)变量并返回出一个对象,2.对象内部每次循环next方法,next方法返回出一个对象,如果不满足条件(done: false)就继续循环,直到done:true停止循环,3.外部每次循环的变量attr即迭代器内部的value变量。
for of迭代过程:1.循环前先判断是否有symbol.iterator方法 2.有迭代器方法后继续执行next函数,next函数会被多次执行 3.直到next函数内部的done属性为true时停止循环
for...of方法的实现,迭代value
var obj = {
left: 100,
top: 200
}
obj[Symbol.iterator] = function() {
let keys = Object.keys(obj); //['left', 'top']
let len = keys.length; //迭代的次数
let n = 0; //当前迭代第几次
return {
next: function () {
if (n < len> {
return {
// [n++] 先赋值[n],再++
// value: keys[n++],
value: obj[keys[n++]]; //迭代的返回值
// value {key: keys[n], value: obj[keys[n++]]},
done: false
} else {
return {
done: true
}
}
}
}
for (var attr of obj) {
console.log(attr);
}
// left top
// 100 200
三、冻结对象
const arr = [1, 2 ,3];
- const 声明的变量不可修改,但是数组可以通过
push
的方式推入新值
arr.push(4);
console.log(arr) // [1, 2, 3, 4];
- 使用冻结对象禁止数组扩展
const arr = Object.freeze([1, 2, 3]);
arr.push(4);
console.log(arr) // 报错,提示对象不可扩展