[TOC]
> ## :-: [Babel - 官网](https://www.babeljs.cn/)
```
// ES6 转 ES5 ----- 下载插件、
// cnpm install @babel/core
// cnpm install @babel/preset-env
// cnpm install @babel/cli
// 配置文件 --- .babelrc
// {
// "presets": [
// "@babel/preset-env"
// ]
// }
// 执行
// npm babel es6.js -o new-es5.js
```
> ## :-: [ECMAScript 6 入门](http://es6.ruanyifeng.com/)
> ## :-: ES6 - 点点点运算符
```
// ...arr --- 收集
function sum(...arg) {
// ...arg
// arg == arguments 并将类数组转化为数组了、
let sumNumber = 0;
arg.forEach(function(ele) {
sumNumber += ele;
});
return sumNumber;
}
console.log( sum(1, 2, 3, 4, 5, 6) ); // 21
function sum(a, b, ...arg) { console.log(a, b, arg) }
sum(1, 2, 3, 4, 5); // 1 2 [3, 4, 5]
// ...arr --- 展开
let arr = [1, 2, 3];
(function(a, b, c) { console.log(a, b, c) }( ...arr )); // 1 2 3
let arr = [1, 2, 3]
console.log(...arr); // 1 2 3
let arr1 = [1, 2, 3],
arr2 = [4, 5, 6],
newArr = [...arr1, ...arr2]
console.log(newArr); // [1, 2, 3, 4, 5, 6]
// 在ES7中,支持对象浅层克隆、兼容不好
let obj_1 = { name: 'aaa', are: 18, arr: [1, 2, 3] }
let obj_2 = { name: 'bbb', test: 666, obj: { a: 1, b: 2, c: 3 } }
let newObj = {...obj_1, ...obj_2, test: 'hi~' }
console.log(newObj);
```
> ## :-: ES6 - 结构化赋值
```
let obj = { a: 1, b: 2, c: 3 }
let { a, b, c } = obj;
console.log(a, b, c); // 1 2 3
let { a: aa, b: bb, c: cc } = obj;
console.log(aa, bb, cc); // 1 2 3
// 默认赋值 (很常见)
let { d: dd = 100 } = obj;
console.log(dd); // 100
function sum(a = 1, b = 2) { console.log(a, b) }
// 解构数组
let arr = [1, 2, 3]
let { 0: x, 1: y, 2: z } = arr;
console.log(x, y, z); // 1 2 3
let [x, y, z] = arr;
console.log(x, y, z); // 1 2 3
let [, , z, s = 5] = arr;
console.log(z, s); // 3 5
```
> ## :-: ES6 - 箭头函数
```
// 箭头函数特点:
// 1、不用写function关键字
// 2、只能作为函数使用不能new,没有原型
// 3、参数不能重复命名
// 4、返回值可以不写return,但是有时需要配合{}
// 5、内部arguments this由定义时外围最接近一层的非箭头函数的arguments和this决定其值。
let fn = (a, b, c) => { console.log(a, b, c) }
fn(1, 2, 3); // 1 2 3
// 省略 return
let fn = (a, b) => a + b;
fn(5, 10) // 15
// 更加精简的写法、
let sum = x => y => z => x + y + z;
sum(1)(2)(3); // 6
// 箭头函数没有arguments,会向上找(function)
function demo() {
let test = (...arg) => {
console.log(arguments); // [1, 2]
console.log(arg); // [3, 4]
};
test(3, 4);
}
demo(1, 2);
// —— 技巧篇
let obj = {
a: 0,
fn() {
// 箭头函数this为外围function的this,箭头函数没有原型链、
setInterval(() => { console.log(++this.a) }, 500);
}
}
obj.fn();
let arr = [1, 5, 8, 6, 7, 2, 4, 3]
arr.sort( (a, b) => a - b ); // [1, 2, 3, 4, 5, 6, 7, 8]
arr.filter( ele => ele > 5 ); // [6, 7, 8]
```
> ## :-: Object.defineProperty
```
// 在对象上定义一个新的、具有详细描述的属性。或者修改一个对象的现有属性、
// Object.defineProperty(对象,属性,描述符); 返回值:修改后的对象、
let obj = {}
Object.defineProperty(obj, 'name', {
// 数据描述符(不共存):
// value -- 属性值
value: 'cst',
// writable -- 是否可修改(默认false)
// 演示:obj[name] = 'test';
writable: true,
// configurable -- 是否可配置(默认false)
// 演示:delete obj[name];
configurable: true,
// enumerable -- 是否可枚举(默认false)
// 演示:for (let prop in obj) { console.log( obj[prop] ) }
enumerable: true,
// 存取描述符(不共存):
get: function() {
// 当obj[name]被读取时调用该方法,劫持后返回 'get'
return 'get';
},
set: function(val) {
// 对象属性赋值时会经过这个方法,属性值通过val参数传入、
return val;
},
})
```
```
// 简写形式
let newObj = {
tempValue: 'test',
get name() {
return this.tempValue;
},
set name(newValue) {
this.tempValue = newValue;
}
}
console.log( newObj.name );
```
```
// 注意:如果描述符中同时出现,value、writable 和 set、get两组的话,会冲突。切记不要同时使用。
// 作用:双向数据绑定的核心方法,主要做数据劫持操作 (监控属性变化) ,同时是后期ES6中很多语法糖底层实现核心的方法。
```
> ## :-: ES6 - 数据劫持 (2019-6-15)
```
// 将对象的属性名打包成数组、
let obj = { a: 1, b: 2, c: 3 }
console.log( Object.keys(obj) ); // ["a", "b", "c"]
Object.keys(obj).forEach((key) => { console.log(key) })
```
```
// 原对象
let oData = {
val: 'test'
},
// 代理对象
// new Proxy(obj, {···}) -- 植入代理模式的思想,以简洁易懂的方式控制对外部对象的访问、Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
oProxyData = new Proxy(oData, {
set(target, key, value, receiver) {
// target -- 原对象 key -- 属性名 value -- 属性值 receiver -- 代理
console.log(target, key, value, receiver);
// 等同于:target[key] = value;
Reflect.set(target, key);
},
get(target, key, receiver) {
// target -- 原对象 key -- 属性名 receiver -- 代理
console.log(target, key, receiver);
// 等同于:return target[key];
return Reflect.get(target, key);
},
// ···
});
console.log(oProxyData.val); // 'test'
```
> ## :-: ES6 - class定义构造函数 (2019-6-16)
```
// Object.setPrototypeOf(obj, prototype) -- 设置对象的原型。obj : 要设置其原型的对象。prototype : 该对象的新原型(一个对象 或 null)。
// Object.setPrototypeOf(AttackPlane.prototype, Plane.prototype);
// 相当于:AttackPlane.prototype.__proto__ = Plane.prototype;
// Object.create(proto, [propertiesObject]) -- 创建一个新对象,使用现有的对象来提供新创建的对象的原型,proto : 必须,新建对象的原型对象。propertiesObject : 可选,添加到新创建对象的可枚举属性。
// AttackPlane.prototype = Object.create(Plugin.prototype);
Class与普通构造函数有何区别?
1、class在语法上更贴近面向对象的写法。
2、class实现继承更加易读易理解。
// class -- 定义一个构造函数,声明创建一个基于原型继承的具有给定名称的新类。
class Plane extends New {
// Plane 继承自 New 构造函数、
constructor(name) {
// Plane
super(name); // 相当于:New.call(name);
this.name = 'abc';
};
// Plane.prototype
test() {
// test 为原型上的普通函数、
console.log('test');
};
// static abc = 123; // 在ES6中只能添加方法,不能添加普通的属性(会报错)、ES7才能添加(不能直接加)
}
console.log( new Plane('new') );
```
```
// throw 'Error' -- 主动报错
// object instanceof Element -- instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型
```
```
// class -- ES7·定义一个构造函数
class Plane {
abc = 123; // ES7 私有属性的定义方式,跟constructor中this.abc一样、
constructor(name) {
this.name = 'abc';
};
// Plane.prototype
static abc = 123; // 静态属性会被定义在原型上、
test() {
// test 为原型上的普通函数、
console.log('test');
};
}
console.log( new Plane('new') );
```
> ## :-: ES6 - Set / Map (2019-6-19)
```
// Set -- 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
// 参数:如果传递一个可迭代对象,它的所有元素将不重复地被添加到新的 Set中。如果不指定此参数或其值为null,则新的 Set为空。
// [] '' arguments NodeList
// 特点:成员值去重
let oS = new Set([1, 2, 3, [1, 2], true, { name: 'cst' }, 1, 2, true, 4]);
let oStr = new Set('12'); // Set {"1", "2"}
oStr.add(3); // 添加成员:Set {"1", "2", 3}
// .delete() -- 删除成员、
// .clear() -- 清除
// .has() -- 判断
// .forEach() -- 遍历
oStr.forEach(ele => {
console.log(ele);
});
// ES6 of 遍历
for (let prop of oStr) {
console.log(prop);
}
// 转换 -- Set -> []
let arr = [1, 2, 3, 1, 2];
let oArr = new Set(arr); // 将数组类型转为Set类型 Set {1, 2, 3}
// ··· Array.from
Array.from(oArr); // 将Set转为数组类型 [1, 2, 3]
[...oArr] // 将Set转为数组类型 [1, 2, 3]
let arr1 = new Set([1, 2, 3, 1, 2]),
arr2 = new Set([2, 3, 4, 5, 5]),
// 取并集
oArrS = new Set([...arr1, ...arr2]); // Set {1, 2, 3, 4, 5}
// 取交集
let intersectionArr = [...arr1].filter( ele => arr2.has(ele) ); // [2, 3]
// 取差集 ( arr1有arr2没有的值 )
[...arr1].filter( ele => !arr2.has(ele )); // [1]
[...arr2].filter( ele => !arr1.has(ele )); // [4, 5]
```
```
// Map -- 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
let oMp = new Map( [ ['name','cst'],['age',18],['sex',true] ] );
console.log(oMp); // Map {"name" => "cst", "age" => 18, "sex" => true}
// api
// 设值 -- oMp.set('name', 'cst');
// 取值 -- oMp.get('name');
// 删除 -- oMp.delete('name');
// 清空 -- oMp.clear();
// 判断 -- oMp.has('name');
// 长度 -- oMp.size
// 将所有属性名打包成数组 -- oMp.keys();
oMp.forEach((ele, key) => { console.log(ele, key) });
```
```
// lodash.js https://www.lodashjs.com
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js" integrity="sha256-7/yoZS3548fXSRXqc/xYzjsmuW3sFKzuvOCHd06Pmps=" crossorigin="anonymous"></script>
```
> ## :-: ES6 - Promise (2019-6-26)
```
// Promise -- 对象用于表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值。
语法:new Promise( function(resolve, reject) {...} /* executor */ );
// node.js
let fs = require('fs');
fs.readFile('./Untitled-1.txt', 'utf-8', (err, data) => {
console.log(data);
});
// ———————————————————————————————————————————————————————————————————————————————————————————————
// 并发回调、
const Store = {
list: [],
times: 3,
subscribe() {
this.list.push(func);
},
fire(...arg) {
--this.times == 0 && this.list.forEach((ele) => { ele.apply(null, arg) });
}
};
// ———————————————————————————————————————————————————————————————————————————————————————————————
// Promise.all
// executor function 同步执行
// Promise -- 承诺
let oP = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
Math.random() * 100 > 60 ? resolve('ok') : reject('no');
}, 1000);
});
// then -- 成功,失败
oP.then((val) => {
console.log(val);
// throw new Error('-- 主动报错');
// return "返回值会作为下一次then的参数,并且重新调佣 resolve('ok') : reject('no') 方法";
// 返回Promise可以指定下一次then,是执行 resolve() 或者 reject() 。
return new Promise((resolve, reject) => {
reject('2-no');
});
}, (val) => {
console.log(val);
return "返回值会作为下一次then的参数,并且重新调佣 resolve('ok') : reject('no') 方法";
}).then((val) => {
console.log('ok then-2: ' + val);
}, (val) => {
console.log('no then-2: ' + val);
});
```
```
// Promise
let oP = Promise.resolve("ok"); // 直接调佣成功的回调
let oP = Promise.reject("no"); // 直接调佣失败的回调
oP.then( (val)=>{ console.log(val) },(reason)=>{ console.log(reason) } );
// .finally -- 无论成功、失败都会调用该方法。(没有参数)
oP.finally( ()=>{ console.log("over") } );
```
```
const fs = require('fs');
function readFile(path) {
return new Promise((res, rej) => {
fs.readFile(path, 'utf-8', (err, data) => {
if (data) {
res(data);
}
})
})
}
Promise.all([readFile('./data/1.txt'), readFile('./data/2.txt'), readFile('./data/3.txt')])
// 全部触发成功时、触发 then
.then((val) => {
console.log(val); // Array(3) ["111", "222", "333"]
});
// 更多方法、
// Promise.all(iterable);
// Promise.race(iterable);
```
> ## :-: ES6 - Iterator(迭代器) (2019-6-28)
```
// Iterator -- 迭代器
function OuterIterator(o) {
let curIndex = 0;
let next = () => {
return {
value: o[curIndex],
done: o.length == ++curIndex
}
}
return {
next
};
}
let arr = ['a', 'b', 'c'];
let oIt = OuterIterator(arr);
oIt.next(); // Object {value: 1, done: false}
oIt.next(); // Object {value: 2, done: false}
oIt.next(); // Object {value: 3, done: true}
oIt.next(); // Object {value: undefined, done: false}
// ES6 - 遍历数组
for (let ele of arr) { console.log(ele); }
```
```
let obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
// [Symbol.iterator]: function() {
// let curIndex = 0;
// let next = () => {
// return {
// value: this[curIndex],
// done: this.length == ++curIndex
// }
// }
// return {
// next
// }
// },
[Symbol.iterator]: function*() {
let curIndex = 0;
while (curIndex != this.length) {
yield this[curIndex++];
}
}
}
console.log([...obj]); // ["a", "b", "c"]
```
```
// Generator 生成这个迭代对象 生成器函数
function* test() {
yield 'a';
yield 'b';
yield 'c';
return 'abc';
}
let oG = test(); oG.next(); oG.next(); oG.next();
```
> ## :-: node.js - 四行代码写服务器 (2019-6-28)
```
// npm install express
// express -- express框架
let express = require('express'),
app = new express();
// 设置静态文件路径、
app.use(express.static('./page'));
// 设置端口号大于8000、等于80
app.listen(12306);
// 地址:127.0.0.1:12306
```
> ## :-: [ES6模块化 导入|导出](https://www.jianshu.com/p/513ccffd3ced) (2019-7-8)
```
<!-- module -- 标记当前引入的文件为模块 -->
<script type="module" src="./src/entrance.js"></script>
// —————————————————————— './m1.js'
let a = 0,
b = 20,
c = "default",
d = a => { a = "demo"; console.log(a); }
setInterval(() => { a++ }, 1000);
function test() { console.log(a) }
// export { a as name };
// 导出多个变量
export { a, b, c, d, test };
// 默认导出
export default c;
// —————————————————————— './entrance.js'
// node commonJs AMD CMD
// -- ES6模块化
// import -- 导入 export -- 导出
// import引入是同步加载的、
// 导入的变量只能读不能取、导入的变量数据是实时绑定,同步的、
import default_1, { a as a1, b as b1, c as c1, d, test } from "./m1.js";
import default_2 from "./m1.js";
import * as all from "./m1.js";
console.log(all, default_1, a1, default_2);
setInterval(() => {
// 导出的变量数据是实时绑定的、
console.log(a1);
}, 1000);
let btn = document.getElementsByTagName("button")[0];
btn.onclick = () => {
// 模块导入,按需加载、import() 方法的返回值是Promise对象(异步)、
// ({ test }) == 解构赋值、
import ("./m1.js")
.then( ({ test }) => { console.log("val: ", test) })
.catch( err => { console.log("err: ", err) });
};
```
> ## :-: 模板字符串 - [String对象方法](https://www.runoob.com/jsref/jsref-obj-string.html) (2019-7-8)
```
let str = "es";
console.log(`t${str}t`); // 'test'
// 字符串方法
str = "String method";
// 查找字符串中是否包含指定的子字符串。true/false
str.includes("String"); // true
// 返回某个指定的字符串值在字符串中首次出现的位置。
str.indexOf("method"); // 7
```
- 前端工具库
- HTML
- CSS
- 实用样式
- JavaScript
- 模拟运动
- 深入数组扩展
- JavaScript_补充
- jQuery
- 自定义插件
- 网络 · 后端请求
- css3.0 - 2019-2-28
- 选择器
- 边界样式
- text 字体系列
- 盒子模型
- 动图效果
- 其他
- less - 用法
- scss - 用法 2019-9-26
- HTML5 - 2019-3-21
- canvas - 画布
- SVG - 矢量图
- 多媒体类
- H5 - 其他
- webpack - 自动化构建
- webpack - 起步
- webpack -- 环境配置
- gulp
- ES6 - 2019-4-21
- HTML5补充 - 2019-6-30
- 微信小程序 2019-7-8
- 全局配置
- 页面配置
- 组件生命周期
- 自定义组件 - 2019-7-14
- Git 基本操作 - 2019-7-16
- vue框架 - 2019-7-17
- 基本使用 - 2019-7-18
- 自定义功能 - 2019-7-20
- 自定义组件 - 2019-7-22
- 脚手架的使用 - 2019-7-25
- vue - 终端常用命令
- Vue Router - 路由 (基础)
- Vue Router - 路由 (高级)
- 路由插件配置 - 2019-7-29
- 路由 - 一个实例
- VUEX_数据仓库 - 2019-8-2
- Vue CLI 项目配置 - 2019-8-5
- 单元测试 - 2019-8-6
- 挂载全局组件 - 2019-11-14
- React框架
- React基本使用
- React - 组件化 2019-8-25
- React - 组件间交互 2019-8-26
- React - setState 2019-11-19
- React - slot 2019-11-19
- React - 生命周期 2019-8-26
- props属性校验 2019-11-26
- React - 路由 2019-8-28
- React - ref 2019-11-26
- React - Context 2019-11-27
- PureComponent - 性能优化 2019-11-27
- Render Props VS HOC 2019-11-27
- Portals - 插槽 2019-11-28
- React - Event 2019-11-29
- React - 渲染原理 2019-11-29
- Node.js
- 模块收纳
- dome
- nodejs - tsconfig.json
- TypeScript - 2020-3-5
- TypeScript - 基础 2020-3-6
- TypeScript - 进阶 2020-3-9
- Ordinary小助手
- uni-app
- 高德地图api
- mysql
- EVENTS
- 笔记
- 关于小程序工具方法封装
- Tool/basics
- Tool/web
- parsedUrl
- request