-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path21-群接龙.html
164 lines (132 loc) · 5.69 KB
/
21-群接龙.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>群接龙</title>
<script>
// 第一题:编写一个 People 类,使其的实例具有监听事件、触发事件、解除绑定功能。(实例可能监听多个不同的事件,也可以去除监听事件)
class People {
constructor(name) {
this.name = name
this.eventsObj = {}
}
on(eventName, callback) {
if (!this.eventsObj[eventName]) {
this.eventsObj[eventName] = []
}
this.eventsObj[eventName].push(callback)
}
off(eventName, callback) {
if (!this.eventsObj[eventName]) return
this.eventsObj[eventName] = this.eventsObj[eventName].filter(
(cb) => cb !== callback
)
}
emit(eventName, ...args) {
if (!this.eventsObj[eventName]) return
this.eventsObj[eventName].forEach((callback) => callback(...args))
}
sayHi() {
console.log(`Hi, I am ${this.name}`)
}
}
/* 以下为测试代码 */
const say1 = (greeting) => {
console.log(`${greeting}, nice meeting you.`)
}
const say2 = (greeting) => {
console.log(`${greeting}, nice meeting you, too.`)
}
const jerry = new People('Jerry')
jerry.sayHi()
// => 输出:'Hi, I am Jerry'
jerry.on('greeting', say1)
jerry.on('greeting', say2)
jerry.emit('greeting', 'Hi')
// => 输出:'Hi, nice meeting you.' 和 'Hi, nice meeting you, too'
jerry.off('greeting', say1)
jerry.emit('greeting', 'Hi')
// => 只输出:'Hi, nice meeting you, too'
// 第二题:完成 sleep 函数,可以达到下面的效果
const sleep = (delay) => {
return new Promise(resolve => setTimeout(resolve, delay))
}
const anyFunc = async () => {
console.log("123") // 输出 123
await sleep(300) // 暂停 300 毫秒
console.log("456") // 输出 456,但是距离上面输出的 123 时间上相隔了 300 毫秒
}
// anyFunc() // 执行
// 第三题:完成 deepGet 函数,给它传入一个对象和字符串,字符串表示对象深层属性的获取路径,可以深层次获取对象内容
// 思路
// 对于属性路径字符串的拆分,通过 split 函数,以 "." 为分隔符,将其拆分为数组。
// 遍历时,对于数组元素中以 "[]" 结尾的情况,说明该属性是数组,需要特殊处理。通过正则表达式,将 "[]" 前的数字提取出来,作为数组的索引。
// 如果该属性不存在,则直接返回 undefined,结束遍历。
const deepGet = (obj, prop) => {
if (!obj) return undefined;
const path = prop.split(".");
let result = obj;
for (const p of path) {
const match = p.match(/^(.+)\[(\d+)\]$/);
if (match) {
if (!Array.isArray(result[match[1]])) return undefined;
result = result[match[1]][parseInt(match[2])];
} else {
result = result[p];
}
if (!result) return undefined;
}
return result;
};
/** 以下为测试代码 */
console.log(deepGet({
school: {
student: {
name: 'Tomy'
},
},
}, 'school.student.name')); // => 'Tomy'
console.log(deepGet({
school: {
students: [{
name: 'Tomy'
},
{
name: 'Lucy'
},
],
}
}, 'school.students[1].name')); // => 'Lucy'
// 对于不存在的属性,返回 undefined
console.log(deepGet({
user: {
name: 'Tomy'
}
}, 'user.age')); // => undefined
console.log(deepGet({
user: {
name: 'Tomy'
}
}, 'school.user.age')); // => undefined
// 第四题:完成 combo 函数。它接受任意多个单参函数(只接受一个参数的函数)作为参数,并且返回一个函数。它的作为用:使得类似 f(g(h(a))) 这样的函数调用可以简写为 combo(f, g, h)(a)。
const combo = (...funcs) => (arg) =>
funcs.reduceRight((acc, func) => func(acc), arg);
/* 以下为测试代码 */
const addOne = (a) => a + 1;
const multiTwo = (a) => a * 2;
const divThree = (a) => a / 3;
const toString = (a) => a + "";
const split = (a) => a.split("");
split(toString(addOne(multiTwo(divThree(666)))))
// => ["4", "4", "5"]
const testForCombo = combo(split, toString, addOne, multiTwo, divThree);
testForCombo(666)
// => ["4", "4", "5"]
// 第五题:有两个盘子分别放有 5 个和 7 个小球,两个朋友玩游戏:每个人轮流从两个盘子中拿小球,每人每次只能从其中一个盘子中拿,每次可以拿 1 个或者多个(不能一个都不拿),拿到最后一个小球的人算输。问开局先手和后手是否有必胜策略?如果有,请描述必胜策略。
</script>
</head>
<body>
</body>
</html>