# 51.id选择器问题
题
问题变形
- 《你不知道的JS(中)》p126
- id选择器会在全局创建一个同名变量
<body> <div id="foo"></div> <script> console.log(foo); // div#foo (DOM元素) </script> </body>
复制成功
1
2
3
4
5
6
7
2
3
4
5
6
7
# 52.Worker作用
题
server.js
worker.js
test.html
- 《你不知道的JS(中)》p288
- JS是单线程语言,所有的执行都是
单线程操作
- 因此JS的异步不是像JAVA那样多开一个thread线程来进行操作,而是使用
事件轮询机制
- 遇到问题:一个
同步操作
涉及大量计算时程序会卡死:
点击程序卡死按钮后计算器不能正常运行操作,因为单线程正忙着呢
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Worker的作用</title> </head> <body> <button id="temp">点我程序卡死十秒</button> <div>计算器</div> <button id="del">-</button> <div id="num">0</div> <button id="add">+</button> <script> temp.addEventListener('click', () => { const end = Date.now() + 10000; console.log('大量计算中'); while (Date.now() < end) {} console.log('计算完毕'); }); del.addEventListener('click', () => { num.innerText = +num.innerText - 1; }) add.addEventListener('click', () => { num.innerText = +num.innerText + 1; }) </script> </body> </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
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
# 53.正则2
题
解
- 正则检查数字,最多12个数字,小数点后最多三个
const a = '123.33'; // true const b = '1223.3333'; // false const c = '324123.033'; // true const d = '324123'; // true const e = '123456789012'; // true const f = '1234567890122'; // false const g = '12345678.9012'; // false const h = '12345678.012'; // true console.log(valNum(a)); console.log(valNum(b)); console.log(valNum(c)); console.log(valNum(d)); console.log(valNum(e)); console.log(valNum(f)); console.log(valNum(g)); console.log(valNum(h));
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 54.super对象
题
解
《你不知道的JS(下)》p97
const a = { name: 'hdy', say() { console.log(this.name); } }; const b = { age: 18, say: function () { super.say(); console.log(this.age); } } Object.setPrototypeOf(b, a); b.say(); // 输出?
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 55.Symbol问题
题
解
- 《你不知道的JS(下)》p125
- 输出与原因
const age = Symbol('age'); const obj = { name: 'hdy', age: 18, [age]: 19 } console.log(obj.age); console.log(obj[age]);
复制成功
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 56.首屏渲染时间
时间点
判断首屏
图片判断
静态计算
动态计算
- 最精确的开始时间:
performance.timeOrigin
- (慢几十毫秒)首屏index头部加上script
Date.now()
- css加载、html加载、图片加载、script加载
- 每个url请求元素都可以绑定
onload
事件拿到加载完毕事件,如img - 整体加载完毕
window.onload
,加载文件完成后就可以渲染,这里可拿到白屏时间
- 页面渲染
- 加载完后js执行,可能会渲染元素上屏,如:vue组件内有图片,图片地址需要ajax异步得到,图片加载完毕后拿到的是
首屏时间
完全静态的文件可以通过
window.onload
事件中Date.now() - performance.timeOrigin
计算整个文件的加载时间,渲染时间根据浏览器性能差异会慢一点
现在的框架基本都是动态前端页面,所以需要动态计算
,并且首屏时间应该是用户能看到的首屏渲染时间,与看不到的内容无关
# 57.addEventListener移除
removeEventListener
signal
once
<body> <button id="temp">啦啦啦啦</button> <script> function c() { console.log('---') } temp.addEventListener('click', c); setTimeout(() => temp.removeEventListener('click', c), 3000) </script> </body>
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 58.红绿灯
题
解
结束控制
解2
- 实现红绿灯交替打印的异步函数
trafic(3000, 1000, 2000); // red 停3秒 yellow 停1秒 green 停2秒 循环 console.log('同步代码不阻塞');
复制成功
1
2
3
4
2
3
4
# 59.+优先级
题
解
var val = 'smtg'; console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing'); // ??
复制成功
1
2
2
# 60.节流事件
题
解
- 写一个组件,上面显示当前窗口的 width/height
- 要求:
- resize同时要监听
- 监听器的移除
- 节流
# 61.instanceof
题
解
console.log('sdf' instanceof String);
复制成功
1
# 62.this2
题
题
- 这两段代码在浏览器的异同
function A() { this.say = function () { console.log(this.name) }; } window.name = 'iii'; const a = new A(); const say = a.say; say()
复制成功
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
class A { say() { console.log(this.name) }; } window.name = 'iii'; const a = new A(); const say = a.say; say()
复制成功
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 63.数组转对象
题
解
const arr = ['a', 'b', 'c', 'd', 'e', 'f']; console.log(modify(arr)); // {'a': {'b': {'c': {'d': {'e': 'f'}}}}}
复制成功
1
2
3
2
3
# 64.收集所有的DOM元素
题
解
- 输出页面所有的DOM元素的tag(去重)
# 65.多维数组全排列
题
解
const arr = [['A', 'B'], ['a', 'b'], [1, 2]] console.log(sort(arr)); // [ // 'Aa1', 'Aa2', // 'Ab1', 'Ab2', // 'Ba1', 'Ba2', // 'Bb1', 'Bb2' // ]
复制成功
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 66.交并集
交集
并集
function test(arr1, arr2) { return [...(new Set([...arr1, ...arr2]))]; } const arr1 = [1, 2, 3, 4, 5, 6]; const arr2 = [19, 23, 3, 41, 5, 6]; console.log(test2(arr1, arr2))
复制成功
1
2
3
4
5
6
7
2
3
4
5
6
7
# 67.手写继承
解
解
function Parent(data) { this.data = data; } Parent.prototype.foo = function () { console.log(this.data); } function inherit(Foo) { // TODO } var child = new (inherit(Parent))(123); child.foo(); // 123;
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 68.localStorate
题
解
- 设置一个原型方法,让localstorage有set和get方法,比setItem、getItem更好用,能够判断是否有时效性
localStorage.set('name', 'hdy', 1000 * 10); localStorage.set('age', 18, 1000 * 20); setTimout(() => console.log(localStorage.get(name)), 9000); // hdy setTimout(() => console.log(localStorage.get(name)), 11000); // null
复制成功
1
2
3
4
5
2
3
4
5
# 69.手写JSONP实现
解
服务器端
<body> <script> function callback(data) { console.log(data); } (function () { const script = document.createElement('script'); script.src = 'http://localhost:8090'; document.body.appendChild(script); })(); </script> </body>
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 70.无符号计算
题
解
- 力扣 (opens new window)
- 计算
1 + 2 + 3...+ n
,不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
# 71.简易JSX compiler
题
解
const str = `<MyButton color="blue" shadowSize={2}>Click Me</MyButton>`; console.log(compiler(str)); // { // tagName: 'MyButton', // props: { color: 'blue', shadowSize: '2' }, // content: 'Click Me' // }
复制成功
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 72.链式函数
题
解
const pipFn = (val) => {} const add = (val) => val + 2; const sub = (val) => val - 2; const double = (val) => val * 2; const pow = (val) => Math.pow(val, val); pipFn(2).double.pow.do; // 256
复制成功
1
2
3
4
5
6
7
2
3
4
5
6
7
# 73.自定义事件
<body> <button id="add"> +1 </button> <script> const addBtn = document.querySelector("#add"); addBtn.addEventListener("click", () => { let num = localStorage.getItem("num") if (!num) { num = 0; } num = +num + 1; localStorage.setItem("num", num); }); /* 通过自定义事件让 localStorage 变成响应式 */ (() => { const oritinItem = localStorage.setItem; window.localStorage.setItem = (key, val) => { const setItemEvent = new CustomEvent("setLocalStorage", { detail: { key, val } }); dispatchEvent(setItemEvent); oritinItem.call(window.localStorage, key, val) } })() window.addEventListener("setLocalStorage", e => alert(JSON.stringify(e.detail))); </script> </body>
复制成功
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
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
# 74.命名小驼峰转下划线
题
解
const oldName = "getPropertyByName"; const change = (oldName) => {} const newName = change(oldName); console.log(newName); // get_property_by_name
复制成功
1
2
3
4
5
6
2
3
4
5
6
# 74.命名下划线转小驼峰
题
解
const oldName = "get_property_by_name"; const change = (oldName) => {} const newName = change(oldName); console.log(newName); // getPropertyByName
复制成功
1
2
3
4
5
6
2
3
4
5
6
# 75.数组转树
题
解
const arr = [ { id: 2, name: '部门B', parentId: 0 }, { id: 3, name: '部门C', parentId: 1 }, { id: 1, name: '部门A', parentId: 2 }, { id: 4, name: '部门D', parentId: 1 }, { id: 5, name: '部门E', parentId: 2 }, { id: 6, name: '部门F', parentId: 3 }, { id: 7, name: '部门G', parentId: 2 }, { id: 8, name: '部门H', parentId: 4 } ] const obj = arr2Tree(arr);
复制成功
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
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
- output:
const obj = { id: 2, name: '部门B', parentId: 0, children: [ { id: 1, name: '部门A', parentId: 2, children: [ { id: 4, name: '部门D', parentId: 1, children: [ { id: 8, name: '部门H', parentId: 4 } ] }, { id: 3, name: '部门C', parentId: 1, children: [ { id: 6, name: '部门F', parentId: 3 } ] }, ] }, { id: 5, name: '部门E', parentId: 2, }, { id: 7, name: '部门G', parentId: 2 } ] }
复制成功
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
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
# 76.限制请求数量
题
解
const reqs = [ () => new Promise((resolve) => setTimeout(() => resolve(1), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(2), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(3), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(4), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(5), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(6), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(7), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(8), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(9), 1000)).then(res => console.log(res)), () => new Promise((resolve) => setTimeout(() => resolve(10), 1000)).then(res => console.log(res)), ] requestBantch(reqs, 5);
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 77.中文读法转换
题
解
// const num = 123456789012; const num = 123450000099; // const num = 423042340234; console.log(num2String(num)); // 一千二百三十四亿五千六百七十八万九千零一十二 // 一千二百三十四亿五千万零九十九 // 四千二百三十亿四千二百三十四万零二百三十四
复制成功
1
2
3
4
5
6
7
2
3
4
5
6
7
# 78.去除字符串最少重复字符
题
解
// const str = "ababac"; // ababa const str = "aaabbbcceeff"; // aaabbb console.log(removeLessStr(str));
复制成功
1
2
3
4
2
3
4
# 79.归属数组
题
解
const groups = { A: [1,2,3], B: [4,5,6], C: [7,8,9], } console.log(test(8)); // C
复制成功
1
2
3
4
5
6
7
2
3
4
5
6
7
# 80.全排列
题
解
const strArrs = [["A", "B", "C"], ["1", "2", "3"], ["a", "b", "c"]]; console.log(joinArrs(strArrs)); // [ // 'A1a', 'A1b', 'A1c', 'A2a', // 'A2b', 'A2c', 'A3a', 'A3b', // 'A3c', 'B1a', 'B1b', 'B1c', // 'B2a', 'B2b', 'B2c', 'B3a', // 'B3b', 'B3c', 'C1a', 'C1b', // 'C1c', 'C2a', 'C2b', 'C2c', // 'C3a', 'C3b', 'C3c' // ]
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 81.单数组全排列
题
解
const arr = [1, 2, 3]; console.log(fullAlignment(arr)); // [ [ 1 ], [ 1, 2 ], [ 1, 2, 3 ], [ 1, 3 ], [ 2 ], [ 2, 3 ], [ 3 ] ]
复制成功
1
2
3
4
2
3
4
# 82.深拷贝
题
解
const a = { name: "aaa", books: [ "a", "a", "a", "a", ], firends: [ { name: "cc" }, { name: "ddd" } ], born: new Date(), reg: /23/g, symbol: Symbol(1), } const b = deepClone(a);
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 83.this指向
题
解
const obj = { fn1: () => console.log(this), fn2: function() {console.log(this)} } obj.fn1(); obj.fn2(); const x = new obj.fn1(); const y = new obj.fn2();
复制成功
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 84.树每层节点和
题
解
const tree = { value: 2, children: [ { value: 6, children: [ { value: 1 } ] }, { value: 3, children: [ { value: 2 }, { value: 3 }, { value: 4 } ] }, { value: 5, children: [ { value: 7 }, { value: 8 } ] } ] }; const res = layerSum(tree); console.log(res);
复制成功
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 85. 有序数组原地去重
题
解
const arr = [1, 1, 1, 2, 2, 3, 3, 4, 4]; removeRepeat(arr); console.log(arr); // [1, 2, 3, 4]
复制成功
1
2
3
4
2
3
4
# 86.叠词数量
题
解
const str = "abcdaaabbccccdddefgaaa"; console.log(getRepeatNum(str)); // { numOfRepeatChar: 5, lenOfSingleChar: 7 }
复制成功
1
2
3
2
3
# 87.sleep函数
题
解
- sleep函数
- 不阻塞线程
# 88.强密码正则
题
解
- 力扣 (opens new window)
- 密码有至少 8 个字符。
- 至少包含 一个小写英文 字母。
- 至少包含 一个大写英文 字母。
- 至少包含 一个数字 。
- 至少包含 一个特殊字符 。特殊字符为:"!@#$%^&*()-+" 中的一个。
- 它 不 包含 2 个连续相同的字符(比方说 "aab" 不符合该条件,但是 "aba" 符合该条件)。
var strongPasswordCheckerII = function(password) {}; console.log(strongPasswordCheckerII("IloveLe3tcode!")); // true
复制成功
1
2
3
2
3
# 89.辗转相除法(gcd)
题
解
var gcdOfStrings = function(str1, str2) {}; console.log(gcdOfStrings("ABABAB", "ABAB")); // AB
复制成功
1
2
3
2
3
# 90.缓存函数
需求
解
- 已经跑过的就直接拿答案
const fn = (n) => { console.log("run"); return n + n; }; const memoFn = memoization(fn); memoFn(1); memoFn(2); memoFn(1); memoFn(1); memoFn(1); // run // run
复制成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 91.斐波那契
题
递归解
map缓存解
数组缓存
值缓存
- 给数字n
- f(n) = f(n - 1) + f(n - 2)
# 92.LazyMan
题
解1
解2
解3
解4
LazyMan("小黄"); // Hi this is 小黄! LazyMan("小黄").sleep(10).eat("dinner"); // Hi this is 小黄! 等10s, Eat dinner LazyMan("小黄").sleepFirst(5).eat("supper"); // // 等5s Hi this is 小黄! Eat supper
复制成功
1
2
3
2
3
v1.4.16