Skip to content

Commit 521649d

Browse files
es6
1 parent eee83bf commit 521649d

File tree

7 files changed

+407
-7
lines changed

7 files changed

+407
-7
lines changed

02-ES新特性/ES6/04-Map&Set.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* 【 Map 对象 】
1313
* 保存键值对,任何值(对象或原始值)都可以作为键或值
1414
* 初始值必须为kv形式:[[k1,v1],[k2,v2]]
15-
* [ set / delete / clear / size / get / keys / values / entires ]
15+
* [ set / delete / clear / size / get / keys / values / entries ]
1616
* for (let [key, value] of map) {}
1717
* Object.assign(target, source) // 复制
1818
*/

02-ES新特性/ES6/05-Proxy.html

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<!--
2+
* @Author: victorsun
3+
* @Date: 2019-03-23 23:30:05
4+
* @LastEditors: victorsun - csxiaoyao
5+
* @LastEditTime: 2020-03-15 02:07:03
6+
* @Description: [email protected]
7+
-->
8+
<!DOCTYPE html>
9+
<html lang="en">
10+
11+
<head>
12+
<meta charset="UTF-8">
13+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
14+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
15+
<title>es6</title>
16+
</head>
17+
18+
<body>
19+
详细 api 参考 Reflect & Proxy
20+
<script>
21+
/**
22+
* Proxy 代理
23+
*/
24+
// 【 用法1 】: 拦截get / set
25+
let o = {
26+
name: 'csxiaoyao',
27+
price: 100
28+
}
29+
// es5
30+
/*
31+
for (let [key] of Object.entries(o)) {
32+
Object.defineProperty(o, key, {
33+
writable: false
34+
})
35+
}
36+
d.price = 20
37+
console.log(d.price) // 120
38+
*/
39+
// es6 proxy
40+
let d = new Proxy(o, {
41+
get (target, key) {
42+
if (key === 'price') {
43+
return target[key] + 20
44+
} else {
45+
return target[key]
46+
}
47+
},
48+
set (target, key, value) {
49+
return false
50+
}
51+
})
52+
d.price = 10
53+
console.log(d.price) // 120
54+
55+
// 【 用法2 】: 写操作规则校验
56+
let o2 = {
57+
name: 'sunshine',
58+
price: 100
59+
}
60+
// 规则校验
61+
let validator2 = (target, key, value) => {
62+
if (Reflect.has(target, key)) {
63+
if (key === 'price') {
64+
if (value > 300) {
65+
return false
66+
} else {
67+
target[key] = value
68+
}
69+
} else {
70+
target[key] = value
71+
}
72+
} else {
73+
return false
74+
}
75+
}
76+
let d2 = new Proxy(o2, {
77+
get (target, key) {
78+
return target[key] || ''
79+
},
80+
set: validator2
81+
})
82+
d2.price = 301 // 无效
83+
console.log(d2.price, d2.name)
84+
85+
// 【 用法3 】: 监控上报
86+
// 规则校验
87+
let validator3 = (target, key, value) => {
88+
if (Reflect.has(target, key)) {
89+
if (key === 'price') {
90+
if (value > 300) {
91+
// report(...) // 这样不好
92+
throw new TypeError('price exceed 300')
93+
return false
94+
} else {
95+
target[key] = value
96+
}
97+
} else {
98+
target[key] = value
99+
}
100+
} else {
101+
return false
102+
}
103+
}
104+
window.addEventListener('error', (e) => {
105+
console.log(e.message)
106+
// report('./')
107+
})
108+
let d3 = new Proxy(o2, {
109+
get (target, key) {
110+
return target[key] || ''
111+
},
112+
set: validator3
113+
})
114+
// d3.price = 301 // 无效
115+
116+
// 【 用法4 】: uuid
117+
class Component {
118+
constructor () {
119+
this.proxy = new Proxy({
120+
id: Math.random().toString(36).slice(-8)
121+
}, {})
122+
}
123+
get id () {
124+
return this.proxy.id
125+
}
126+
}
127+
let com = new Component()
128+
let com2 = new Component()
129+
for (let i = 0; i < 10; i++) {
130+
console.log(com.id, com2.id)
131+
}
132+
com.id = 'abc'
133+
134+
// 【 扩展 】: 撤销代理
135+
let o3 = {
136+
name: 'sunshine',
137+
price: 100
138+
}
139+
let d4 = Proxy.revocable(o3, {
140+
get (target, key) {
141+
return target[key] || ''
142+
},
143+
set: validator2
144+
})
145+
console.log(d4.proxy.price, d) // 100
146+
setTimeout(() => {
147+
d4.revoke()
148+
setTimeout(() => {
149+
console.log(d4.proxy.price) // 阅后即焚
150+
}, 100)
151+
}, 1000)
152+
</script>
153+
</body>
154+
155+
</html>

02-ES新特性/ES6/05-Reflect.html

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<!--
2+
* @Author: victorsun
3+
* @Date: 2019-03-23 23:30:05
4+
* @LastEditors: victorsun - csxiaoyao
5+
* @LastEditTime: 2020-03-15 01:26:27
6+
* @Description: [email protected]
7+
-->
8+
<!DOCTYPE html>
9+
<html lang="en">
10+
11+
<head>
12+
<meta charset="UTF-8">
13+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
14+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
15+
<title>es6</title>
16+
</head>
17+
18+
<body>
19+
详细 api 参考 Reflect & Proxy
20+
<script>
21+
/**
22+
* Relect 反射
23+
* 编译阶段不知道是哪个类被加载,执行阶段才加载
24+
*/
25+
// 【 用法1 Reflect.apply 】: 改变指向
26+
// 使用 es5 apply
27+
console.log(Math.floor.apply(null, [3.72]))
28+
// 使用 es6 reflect
29+
console.log(Reflect.apply(Math.floor, null, [4.72]))
30+
31+
// 【 用法2 Reflect.apply 】: 动态确定执行哪个类
32+
let price = 91.5
33+
// 使用 es5 apply
34+
if (price > 100) { price = Math.floor.apply(null, [price]) }
35+
else { price = Math.ceil.apply(null, [price]) }
36+
// 使用 es6 reflect
37+
console.log(Reflect.apply(price > 100 ? Math.floor : Math.ceil, null, [price]))
38+
39+
// 【 用法3 Reflect.construct 】: 调用不同类实例化
40+
let d = Reflect.construct(Date, []) // new Date()
41+
console.log(d.getTime(), d instanceof Date) // xxx true
42+
43+
// 【 用法4 Reflect.defineProperty 】: 设置属性,与 Object 方法一致,除了返回值
44+
const student = {}
45+
// es5 返回 {name1: "Mike1", name2: "Mike2"}
46+
var ret1 = Object.defineProperty(student, 'name1', { value: 'Mike1' })
47+
// es6 返回 true
48+
var ret2 = Reflect.defineProperty(student, 'name2', { value: 'Mike2' })
49+
50+
// 【 用法5 Reflect.get 】: 读取对象属性
51+
const obj = { x: 1, y: 2 }
52+
console.log(Reflect.get(obj, 'x')) // obj.x 1
53+
console.log(Reflect.get([3, 4], 1)) // [3,4][1] 4
54+
55+
// 【 用法6 Reflect.getOwnPropertyDescriptor 】: 获取属性描述符
56+
// 返回 {value: 1, writable: true, enumerable: true, configurable: true}
57+
console.log(Object.getOwnPropertyDescriptor(obj, 'x'))
58+
console.log(Reflect.getOwnPropertyDescriptor(obj, 'x'))
59+
60+
// 【 用法7 Reflect.has 】: 判断属性是否存在
61+
console.log(Reflect.has(obj, 'x')) // true
62+
63+
// 【 用法8 Reflect.preventExtensions / Reflect.isExtensible 】: 对象冻结 & 判断是否冻结
64+
// es5
65+
Object.freeze(obj)
66+
obj.z = 3
67+
console.log(obj) // {x: 1, y: 2}
68+
// es6
69+
Reflect.preventExtensions(obj)
70+
console.log(Reflect.isExtensible(obj)) // false
71+
Reflect.set(obj, 'z', 4)
72+
console.log(obj) // {x: 1, y: 2}
73+
74+
// 【 用法9 Reflect.ownKeys 】: 判断属性是否存在
75+
console.log(Reflect.ownKeys(obj)) // ["x", "y"]
76+
console.log(Reflect.ownKeys([1,2])) // ["0", "1", "length"]
77+
78+
// 【 用法10 Reflect.set 】: 设置值
79+
const arr = ['duck', 'duck', 'duck']
80+
Reflect.set(arr, 2, 'goose')
81+
console.log(arr) // ["duck", "duck", "goose"]
82+
83+
// 【 用法11 Reflect.getPrototypeOf / Reflect.setPrototypeOf 】: 原型相关
84+
console.log(Reflect.getPrototypeOf(arr))
85+
Reflect.setPrototypeOf(arr, String.prototype)
86+
// console.log(Reflect.getPrototypeOf(arr))
87+
88+
</script>
89+
</body>
90+
91+
</html>

02-ES新特性/ES6/11-ES6迭代器.html renamed to 02-ES新特性/ES6/11-ES6-iterator迭代器.html

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,104 @@
88
</head>
99
<body>
1010
<script>
11+
// 问题:需要收集下面结构中所有的作者名
12+
let authors = {
13+
allAuthors: {
14+
fiction: ['aa', 'bb', 'cc'],
15+
scienceFiction: ['dd', 'ee'],
16+
fantasy: ['ff', 'gg']
17+
},
18+
address: []
19+
}
20+
let authors2 = {
21+
allAuthors: {
22+
fiction: ['aa', 'bb', 'cc'],
23+
scienceFiction: ['dd', 'ee'],
24+
fantasy: ['ff', 'gg']
25+
},
26+
address: []
27+
}
28+
// es5,需要每次自己写遍历逻辑,不够优雅,希望针对 authors,能用统一一种如 push 的方式实现(控制遍历的指针)
29+
let r = []
30+
for (let [,v] of Object.entries(authors.allAuthors)) {
31+
r = r.concat(v)
32+
}
33+
console.log(r) // ["aa", "bb", "cc", "dd", "ee", "ff", "gg"]
34+
35+
/**
36+
* 迭代器定义
37+
*/
38+
// 1. 在对象上绑定 Symbol.iterator
39+
// 2. 固定输入为 this
40+
// 3. 约束输出格式,next / done / value
41+
/*
42+
authors[Symbol.iterator] = function () {
43+
return {
44+
next () { // next
45+
return {
46+
done: false, // done 必填,遍历是否结束
47+
value: 1 // value 必填,当前遍历项的值
48+
}
49+
}
50+
}
51+
}
52+
*/
53+
authors[Symbol.iterator] = function () {
54+
// 固定输入 this
55+
let allAuthors = this.allAuthors
56+
let keys = Reflect.ownKeys(allAuthors)
57+
let values = []
58+
// 输出格式约束
59+
return {
60+
next () { // next
61+
if (!values.length) {
62+
if (keys.length) {
63+
values = allAuthors[keys[0]] // 0是因为用完后剔除
64+
keys.shift()
65+
}
66+
}
67+
return {
68+
done: !values.length, // done 必填,遍历是否结束
69+
value: values.shift() // value 必填,当前遍历项的值
70+
}
71+
}
72+
}
73+
}
74+
let r2 = []
75+
for (let v of authors) {
76+
r2.push(v)
77+
}
78+
console.log(r2) // ["aa", "bb", "cc", "dd", "ee", "ff", "gg"]
79+
80+
/**
81+
* 扩展使用 generator 协议,应用上述的 迭代器协议
82+
*/
83+
authors2[Symbol.iterator] = function * () {
84+
let allAuthors = this.allAuthors
85+
let keys = Reflect.ownKeys(allAuthors)
86+
let values = []
87+
while (1) {
88+
if (!values.length) {
89+
if (keys.length) {
90+
values = allAuthors[keys[0]]
91+
keys.shift()
92+
yield values.shift()
93+
} else {
94+
return false
95+
}
96+
} else {
97+
yield values.shift()
98+
}
99+
}
100+
}
101+
let r3 = []
102+
for (let v of authors2) {
103+
r3.push(v)
104+
}
105+
console.log(r3) // ["aa", "bb", "cc", "dd", "ee", "ff", "gg"]
106+
11107
/**
12108
* 迭代的过程
13-
*
14109
*/
15110
// 1. 通过 Symbol.iterator 创建一个迭代器,指向当前数据结构的起始位置
16111
// 2. 通过 next 方法向下迭代指向下一个位置, next 方法返回当前位置的对象(包含当前属性值 value 和是否遍历结束 done 两个属性)

0 commit comments

Comments
 (0)