1. promise简单实现
javascript
1 | function _Promise(fn) { |
2. react性能优化
React 16 加载性能优化指南
- 首屏 -> 避免空白:在app root节点中加入loading提示;
- 首屏 -> 内容渲染:
- 可优化资源:
- 基础框架:如 React、Vue 等,这些基础框架的代码是不变的,除非升级框架;
- Polyfill:对于使用了 ES2015+ 语法的项目来说,为了兼容性,polyfill 是必要的存在;
- 业务基础库:业务的一些通用的基础代码,不属于框架,但大部分业务都会使用到;
- 业务代码:特点是具体业务自身的逻辑代码;
- 缓存基础框架:制定合适的缓存策略,四种缓存的优先级:cache-control > expires > etag > last-modified;
- 使用动态 polyfill:
- 去掉构建中静态的 polyfill,换而使用 polyfill.io 这样的动态 polyfill 服务,保证只有在需要时,才会引入 polyfill;
- 编译到 ES2015+ ,提升代码运行效率,利用《script type=”module”》标签检测是否支持信语法;html
1
2
3
4<script type="module" src="main.es2016.js;"></script>
<script nomodule src="main.es5.js"></script>
// 1. 新浏览器识别module和nomodule,会只加载main.es2016.js;
// 2. 旧浏览器不识别module和nomodule,会只加载main.es5.js;
- 使用 SplitChunksPlugin 自动拆分业务基础库;
- 业务代码:
- 使用 Tree Shaking 减少业务代码体积,去除没有用到的代码;
- Code Splitting “懒加载”代码,改成动态import的形式(React Loadable组件);
- shouldComponent()避免不必要的diff;或者启用PureComponent,自带shouldComponent浅比较props和state;
- list类型的同级节点加key属性;
- 页面图片懒加载:监听scroll(节流);
- 可优化资源:
React 框架级别性能优化
- 任务分片(React Fiber):基于浏览器对 requestIdleCallback 和 requestAnimationFrame 这两个API 的支持,React 团队实现新的调度策略 — Fiber reconcile。
- 结合 Web worker:
- React 结合 Web worker:
- 标准的 React 应用由两部分构成:
- React core:负责绝大部分复杂的 Virtual DOM 计算;
- React-Dom:负责与浏览器真实 DOM 交互来展示内容。
- 我们尝试在 Web worker 中运行 React Virtual DOM 的相关计算。即将 React core 部分移入 Web worker 线程中。
- worker线程postMessage通信的成本决定更新少部分节点的性能不好;
- 标准的 React 应用由两部分构成:
- Redux 结合 Web worker:
- 将 Redux 中 reducer 复杂的纯计算过程放在 worker 线程里;
- 在实现层面,借助 Redux 库的 enchancer 设计,完成了抽象封装;
- React 结合 Web worker:
web前端性能优化
- 内容优化
- 减少HTTP请求数:合并多个CSS文件和js文件,利用CSS Sprites整合图像,合理设置HTTP缓存等。
- 使用内容分发网络(CDN)
- 使用Ajax缓存
- 避免重定向
- 延迟加载组件,预加载组件
- 最小化iframe的数量
- CSS优化
- 将CSS代码放在HTML页面的顶部
- 避免使用CSS表达式
- javascript优化
- 将JavaScript脚本放在页面的底部
- 谨慎使用with,避免使用eval Function函数
- 最小化DOM的访问:使用JavaScript访问DOM元素比较慢
web安全
- 因输入/输出值转义不完全引发的安全漏洞:
- SQL注入;
- 跨站脚本攻击(XSS) + 会话劫持::利用没转义的输出构建script标签,将用户信息发送给自己的服务器,获取用户数据(cookie),就可以伪装成用户发送请求了;
- 跨站点请求伪造(CSRF):利用img.src的属性,在用户不知情的情况下,发送请求(如购物);
- 其他安全漏洞:
- 密码破解:穷举法,字典攻击;
- 点击劫持(iframe透明覆盖);
- Dos攻击:利用大量请求造成资源过载;
算法
- 冒泡排序javascript
1
2
3
4
5
6
7
8
9
10this.bubbleSort = function() {
const length = array.length;
for (let i = 0; i < length; i++) {
for (let j = 0; j < length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
[array[j], array[j + 1]] = [array[j + 1], array[j]];
}
}
}
}; - 快速排序:在数组中间选择一个主元,交换两边的元素,让主元左边的元素小于主元,右边的元素大于主元;再对两边重复这个步骤;javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 易理解版(阮一峰):没有考虑时间空间复杂度,保留核心思想-分治
const quickBrief = function(array) {
if (array.length <= 1) return array;
const pivotIndex = Math.floor(array.length / 2);
const pivot = array.splice(pivotIndex, 1)[0];
const left = [];
const right = [];
for (let i = 0; i < array.length; i++) {
if (array[i] < pivot) {
left.push(array[i]);
} else {
right.push(array[i]);
}
}
return quickBrief(left).concat([pivot], quickBrief(right));
}; - 归并排序javascript
1
2
3
4
5
6
7
8
9
10
11
12
13function merge(leftArr, rightArr) {
const resultArr = [];
while (leftArr.length && rightArr.length) {
resultArr.push(leftArr[0] < rightArr[0] ? leftArr.shift() : rightArr.shift());
}
return resultArr.concat(leftArr, rightArr);
}
function mergeSort(arr) {
if (arr.length < 2) return arr;
const mid = Math.floor(arr.length / 2);
return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)));
}
三栏布局
参考:三栏布局
- float布局;
- position: absolute;
- display: table;
- display: flex;
- display: grid;
http 2.0 (SPDY协议是Google提出的)
- header压缩:HTTP/2使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
- 二进制分帧:HTTP 2.0 的所有帧都采用二进制编码
- 多路复用:有了新的分帧机制后,HTTP/2 不再依赖多个TCP 连接去实现多流并行了;HTTP 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个域名一个连接)即可。
- 服务端推送
实现超出整数存储范围的两个大正整数相加
javascript
1 | const num1 = '1118911'; |
函数式编程
- 纯函数:无副作用(不改变参数,不依赖环境,不进行请求,I/O操作);如map, slice等;
- 声明式代码javascript
1
2
3
4
5
6
7// 命令式
const makes = [];
for (let i = 0; i < cars.length; i++) {
makes.push(cars[i].make);
}
// 声明式
const makes = cars.map(function(car){ return car.make; }); - 函数柯里化javascript
1
2
3
4
5
6
7
8// 普通写法
const add = function(x, y) {
return x + y;
}
// curry
const addCurry = x => y => (x + y);
const addTen = addCurry(10);
const num = addTen(1); - 函数组合javascript
1
2
3
4
5
6
7
8
9const toUpperCase = x => x.toUpperCase();
const exclaim = x => x + '!';
// 普通
const shout = x => exclaim(toUpperCase(x));
console.log(shout('what happened!'));
// 函数组合
const compose = (...funcList) => x => funcList.reduce((pre, cur) => cur(pre), x);
const shoutCompose = compose(toUpperCase, exclaim);
console.log(shoutCompose('what happened!')); - Point Free:函数无须提及将要操作的数据是什么样的javascript
1
2
3
4
5
6// 非 pointfree,因为提到了数据:word
const snakeCase = function (word) {
return word.toLowerCase().replace(/\s+/ig, '_');
};
// pointfree
const snakeCase = compose(replace(/\s+/ig, '_'), toLowerCase);
CSS层叠顺序
层叠顺序 (层叠次序, 堆叠顺序, Stacking Order) 描述的是元素在同一个层叠上下文中的顺序规则,从层叠的底部开始,共有七种层叠顺序:
- 背景和边框:形成层叠上下文的元素的背景和边框。
- 负z-index值:层叠上下文内有着负z-index值的定位子元素,负的越大层叠等级越低;
- 块级盒:文档流中块级、非定位子元素;
- 浮动盒:非定位浮动元素;
- 行内盒:文档流中行内、非定位子元素;
- z-index: 0:z-index为0或auto的定位元素, 这些元素形成了新的层叠上下文;
- 正z-index值:z-index 为正的定位元素,正的越大层叠等级越高;
JavaScript设计模式
- 单例模式javascript
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/**
* 在执行当前 Single 只获得唯一一个对象
*/
var Single = (function(){
var instance;
function init() {
//define private methods and properties
//do something
return {
//define public methods and properties
};
}
return {
// 获取实例
getInstance:function(){
if(!instance){
instance = init();
}
return instance;
}
}
})();
var obj1 = Single.getInstance();
var obj2 = Single.getInstance();
console.log(obj1 === obj2); - 工厂模式javascript
1
2
3
4
5
6
7
8
9
10
11function Animal(opts){
var obj = new Object();
obj.name = opts.name;
obj.color = opts.color;
obj.getInfo = function(){
return '名称:'+obj.name +', 颜色:'+ obj.color;
}
return obj;
}
var cat = Animal({name: '波斯猫', color: '白色'});
cat.getInfo(); - 构造函数模式javascript
1
2
3
4
5
6
7
8
9
10
11
12
13/**
* 构造一个动物的函数
*/
function Animal(name, color){
this.name = name;
this.color = color;
this.getName = function(){
return this.name;
}
}
// 实例一个对象
var cat = new Animal('猫', '白色');
console.log( cat.getName() ); - 发布订阅模式javascript
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/**
* 发布订阅模式
*/
var EventCenter = (function(){
var events = {};
/*
{
my_event: [{handler: function(data){xxx}}, {handler: function(data){yyy}}]
}
*/
// 绑定事件 添加回调
function on(evt, handler){
events[evt] = events[evt] || [];
events[evt].push({
handler:handler
})
}
function fire(evt, arg){
if(!events[evt]){
return
}
for(var i=0; i < events[evt].length; i++){
events[evt][i].handler(arg);
}
}
function off(evt){
delete events[evt];
}
return {
on:on,
fire:fire,
off:off
}
}());
var number = 1;
EventCenter.on('click', function(data){
console.log('click 事件' + data + number++ +'次');
});
EventCenter.off('click'); // 只绑定一次
EventCenter.on('click', function(data){
console.log('click 事件' + data + number++ +'次');
});
EventCenter.fire('click', '绑定'); - 模块模式javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/**
* 模块模式 = 封装大部分代码,只暴露必需接口
*/
var Car = (function(){
var name = '法拉利';
function sayName(){
console.log( name );
}
function getColor(name){
console.log( name );
}
return {
name: sayName,
color: getColor
}
})();
Car.name();
Car.color('红色'); - 代理模式(利用ES6的proxy代理)
vue和react的区别
- jsx语法(all in js)和模板语法;
- 状态数据不可变(函数式)和监听数据对象的变化;
- Fiber分块执行;
- 相互借鉴:reselect和computed;
浏览器兼容
- 不同浏览器的标签默认的外补丁和内补丁不同
解决:css里 *{margin:0;padding:0;} - 几个img标签放在一起的时候,默认有间距
解决:使用float属性为img布局 - 块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大
解决:设置display:inline; - 当标签的高度设置小于10px,在IE6、IE7中会超出自己设置的高度
解决:超出高度的标签设置overflow:hidden,或者设置line-height的值小于你的设置高度 - 标签最低高度设置min-height不兼容
解决:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;} - js相关就用polyfill和babel;
JavaScript继承
javascript
1 | // ES5 组合继承 |
斐波那契序列
javascript
1 | // 1. 递归(普通版) |
git分支管理策略
- master分支:稳定主分支,最后合并,发布版本;
- dev分支:开发分支;
- featrue分支:开发新特性;
- bugfix分支:修改bug;
bootstrap特点
- 跨浏览器:可以兼容所有现代浏览器,包括比较诟病的IE7、8;
- 响应布局;
- 提供了全面的组件,包括:导航,标签,按钮,表单等;jquery插件;
- 支持sass动态样式;
new和bind的相关实现
javascript
1 | function _new(fn){ |
千分位
javascript
1 | function toS(num) { |
Javascript中valueOf与toString区别
- valueOf应用于运算,toString应用于显示.
- 在进行对象转换成字符串时(例如:alert(test)),将优先调用 toString,如果没有 toString 方法了,就调用 valueOf方法,如果tostring 和 valueOf都没重写,就按照 Object的toString 方法输出.
- 在进行强转字符串类型时将优先调用toString方法,强转为数字时优先调用valueOf。
- 在有运算操作符的情况下,valueOf的优先级高于toString。
git merge 和 git rebase 区别
transform: translateZ(0)
gpu加速:元素本身使用transform和opacity做CSS动画的时候,会提前告诉GPU动画如何开始和结束及所需要的指令;所以会创建一个复合层(渲染层),并把页面所有的复合层发送给GPU;作为图像缓存,然后动画的发生仅仅是复合层间相对移动。
http请求方法
- GET:获取资源
- POST:传输实体文本
- PUT:传输文件
- DELETE:删除文件
- HEAD:获得报文首部
- OPTIONS:询问支持的方法
- TRACE:追踪路径
- CONNECT:要求用隧道协议连接代理
post四种content-type
- application/x-www-form-urlencoded (默认):
- 参数形式:提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码;
- multipart/form-data:
- 使用表单上传文件时;
- Content-Type 里指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容;
- 参数形式:消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 –boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 –boundary– 标示结束。
- application/json:
- 各大浏览器都原生支持 JSON.stringify;
- 可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口;
- 参数形式:{“title”:”test”,”sub”:[1,2,3]}
- text/xml:
- 它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范;
- XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便;
CSS实现等比例缩放的盒子:
- padding-bottom有一个非常重要的特性,即当它的值是百分比形式时,百分比的基数是其所在元素的父元素的宽度,而不是高度;
- 具体的解决方案是:将元素的高度height设为0,使其高度等于该元素的padding-bottom,再合理设置该元素padding-bottom的值
jQuery组件封装
javascript
1 | // html |
盒子碰撞
- 反证法比较容易:列出几种不相交的情况;
高阶组件
释义:高阶组件的概念应该是来源于JavaScript的高阶函数,高阶组件仅仅只是是一个接受组件组作输入并返回组件的函数;
- 代理方式;
- 继承方式;
可控组件和不可控组件(input)
- 非可控组件:
- defaultValue用于非可控组件初始化input的value值;
- 非约束性组件的value就是原生的DOM管理的,想要获取值的时候通过ref获取dom引用来获取值;
- 可控组件:
- 由React管理了组件的value;
- input的value指定为组件state中的值;
- onchange指定输入事件处理函数,通过改变state将改变的值反应到view上;
react key
彩蛋:一周面试记录
总结:面试不易,且工作且珍惜!
9.27: 面试初尝试,知道可能会不顺利,但是没想到打击这么大!面试官说:你的简历写的很糟糕!回公司路上坐了第一次两层公交,小安慰!
9.28: 面了一个很小的公司,但是感觉方向不对,他们要招node相关方向:动画 函数式编程 callback全局异常处理
9.30: 电话面试,感觉紧张的不行,要对自己的项目和使用过的技术要熟悉!马上十一了,先放下出去好好玩吧。
10.10: 今天约了两个面试,感觉都还行,不过算法答得很烂!
10.15: 早上面试一个小公司,但是那公司的环境真的好棒呀!可是问的好多都不会,很多回答乱答!下午面试面了一半,另一人有事~失望…都预约了,怎么这样!!!
10.16: 早上一个教室网,面试了一会儿就让回了,感觉不受尊重!下午面头条,感觉大公司环境真的不一样!面试的要求也挺高,自己很多都记不太清楚,实在是水平有限!
10.17: 面试百度,感觉面试官很nice,面了三面,但中间一面回答不好,可惜了!
最后收到了2个offer,真是意外之得,开心!