欢迎 star!
前言
其实,现在已经总结的够多了,大家可以看看:
- 以及上篇都挺不错的
但是看过了还是很容易就忘了,还是得自己敲一遍好。就总结一些自己有问题的地方吧
自己遇到以及整理的一些点:
1. this 的指向:
const a = { count:1, b:{ count: 2, getCount: function(){ console.log(this.count); } }}const getb = a.b.getCountconsole.log(getb())console.log(a.b.getCount()) // 这里要注意不要被迷惑了 复制代码
理解的话,首先要明确的是 this 是在函数里面,在函数调用时动态指定的,指向当前函数(方法)的执行栈(上下文)。 可以查看
2. 正则匹配判断
一个字符串只由[](){}
这几种构成,要求写一个函数 isMatch(str)
匹配如下格式 (1)({[())]}
(2)([{({[]})})]
,结果返回 boolean
分析:要求有两个
- 它们是成对出现的
[{(
分别都是在}])
的前面 后来的代码实现:
function updateStr(str, reg) { let isLoop = true; let result = str; while (isLoop) { result = result.replace(reg, (val, str1, str2) => { val = val.substring(1, val.length - 1); return val; }); if (!reg.test(result)) { isLoop = false; } } return result;};function isMatch(str) { const reg1 = /(\()[\{\}\(\[\]]*(\))/; // 每次匹配一个 (),然后去除 const reg2 = /(\{)[\(\)\{\[\]]*(\})/;// 每次匹配一个 {},然后去除 const reg3 = /(\[)[\[\(\)\{\}]*(\])/;// 每次匹配一个 [],然后去除 const REGS = [reg1, reg2, reg3]; const result = REGS.reduce((total, reg, index) => { return updateStr(total, reg); }, str); return !result;}// 测试let strArray = ['}([(())]){', '{[{([(())])})', '{ {[[{([(())])}))'];let result = strArray.map(val => { return isMatch(val);});console.log(result); // https://leetcode.com/problems/valid-parentheses/submissions/1function isMatch(str) { let map = { '(': -1, ')': 1, '[': -2, ']': 2, '{': -3, '}': 3 }; let stack = []; for (let i =0; i < str.length; i++){ if(map[str[i]] < 0){ stack.push(str[i]); }else{ let last = stack.pop(); if(map[last] + map[str[i]] !==0) return false; } } return stack.length <= 0;}复制代码
3. 实现一个 LazyMan 的对象
要求如下
LazyMan('Tony');// Hi I am TonyLazyMan('Tony').sleep(10).eat('lunch');// Hi I am Tony// 等待了10秒...// I am eating lunchLazyMan('Tony').eat('lunch').sleep(10).eat('dinner');// Hi I am Tony// I am eating lunch// 等待了10秒...// I am eating dinerLazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');// Hi I am Tony// 等待了5秒...// I am eating lunch// I am eating dinner// 等待了10秒...// I am eating junk food复制代码
关键点:
- 实现一个事件队列,每次
shift()
调用一个 - 链式调用
4. 将一维数组通过 pid 转成多维数组:
要求:
const previous = [{ name: "1", id: 1, pid: 0 }, { name: "2", id: 2, pid: 1 }, { name: "3", id: 3, pid: 2 }] const result = [{ name: "1", id: 1, pid: 0, children:[{ name: "2", id: 2, pid: 1 }] },{ name: "3", id: 3, pid: 2 } ]复制代码
要点:
- 递归
- 判断每一个 item 是否属于 tree 中元素
- 找到它的 parent,并把 item 添加到它的 children 中,返回一个新的 tree
其实就是树的不同表现形式
代码实现可以看这里
5. 模拟实现加法器
2个正整数字符串的相加,即 '1'+'19' --> '20',注意考虑超长字符串相加
思路:
- 超级长,不能用 parseInt,它有最大值的限制
Number.MAX_VALUE
- 模拟实现一个十进制的加法器
- 可以扩展支持任意进制的运算
6. AMD,CMD,CommonJs,ES6 Module:解决原始无模块化的痛点
- AMD:requirejs 在推广过程中对模块定义的规范化产出,提前执行,推崇依赖前置
- CMD:seajs 在推广过程中对模块定义的规范化产出,延迟执行,推崇依赖就近
- CommonJs:模块输出的是一个值的 copy,运行时加载,加载的是一个对象(module.exports 属性),该对象只有在脚本运行完才会生成
- ES6 Module:模块输出的是一个值的引用,编译时输出接口,ES6 模块不是对象,它对外接口只是一种静态定义,在代码静态解析阶段就会生成。
7. HTTP 缓存有哪几种?
关键: ETag、CacheControl、Expires 参考
8. 一些 webpack -- 按需加载?构建速度?
参考
9.
10.
11.
12. web 安全
13.
- 启用新的一级域名,每次请求浏览器不会携带cookie。这对于cookie内容比较大,并且流量大的网站会省去不少宽带费用。同时这也解惑了为什么不用二三级域名。
- 动静分离。静态资源与动态内容分离,有利于部署于CDN,减轻web服务器压力
- HTTP协议对同一个域名的同时下载线程数有限制。主要是为了优化下载速度,防止同一域名下下载线程数过多,导致下载速度变慢。各个浏览器都会遵守这个规定,但是限制的数目可能不一致。基于这个原因,可将资源部署于不同的域名,以达到最大化并发下载。
- 静态资源独立部署,为全局产品服务。这属于业务划分的范畴了。比如taobao.com和tmll.com都会用到tbcdn.cn上的静态资源,这些资源不必从属于某个产品。
- 接第4点原因,有利于最大化利用客户端缓存。比如访问taobao.com,缓存了tbcdn.cn上的某个js文件,之后再访问tmll.com时,也用到此js文件,不必再从tbcdn.cn上下载,直接用客户端缓存即可。
同时,就已经减轻了每台服务器的压力,服务器越多,每个服务器压力就越小
13. react 相关
查看我的
总结
平时学习就要多假设一下,为什么会这样,如果换成那个(那里)又会怎么样,这两者比较起来有什么不同!总之要多总结回顾,你会有不一样的感受
还在更新当中,如果有错误,欢迎指正
参考
- 木易杨说的