[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