两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
function twosum(nums, target) {
let map = new Map();
for (let i = 0; i < nums.length; i++) {
let comp = target - nums[i];
if (map.has(comp)) {
return [map.get(comp), i];
} else {
map.set(nums[i], i);
}
}
return [];
}
有效括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 示例 1: 输入:s = "()" 输出:true 示例 2: 输入:s = "()[]{}" 输出:true 示例 3: 输入:s = "(]" 输出:false 示例 4: 输入:s = "([)]" 输出:false 示例 5: 输入:s = "{[]}" 输出:true
function isValid(s) {
let map = new Map();
map.set("(", ")");
map.set("[", "]");
map.set("{", "}");
let arr = [];
for (let i = 0; i < s.length; i++) {
if (map.has(s[i])) {
arr.push(map.get(s[i]));
} else {
if (arr.pop() !== s[i]) {
return false;
}
}
}
if (arr.length !== 0) {
return false;
}
return true;
}
css垂直居中
- 子元素绝对定位
.box {
width: 100px;
height: 100px;
position: absolute;
left: 0px;
right: 0px;
bottom: 0px;
top: 0px;
margin: auto;
background-color: red;
}
- flex
body{
display:flex;
justify-content:center;
align-items:center;
height: 100vh;
width:100%
}
.box{
width: 100px;
height: 100px;
background:red;
}
- 绝对定位
.box {
position: absolute;
width: 100px;
height: 100px;
background: red;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}
- 绝对定位+transform
.box{
position:absolute;
width:100px;
height:100px;
background:red;
top:50%;
left:50%;
transform:translate(-50%,-50%)
}
左右定宽中间自适应固定布局
- flex
.flexbox {display: flex; margin-top: 220px;}
.flexbox .left {
width: 200px;
background-color: #f00;
}
.flexbox .center {
flex: 1;
background-color: green;
}
.flexbox .right {
width: 200px;
background-color: #ff0;
}
- float
.wrap > div {height: 200px; text-align: center; line-height: 200px; }
.float .left {
width: 200px;
float: left;
background-color: #f00;
}
.float .center {
background-color: green;
}
.float .right {
width: 200px;
float: right;
background-color: #ff0;
}
- position
.position .left {
width: 200px;
position: absolute;
left: 0;
background-color: #f00;
}
.position .center {
background-color: green;
position: absolute;
left: 200px;
right: 200px;
}
.position .right {
width: 200px;
position: absolute;
right: 0;
background-color: #ff0;
}
- table
.table {display: table; width: 100%;}
.table > div {display: table-cell}
.table .left {
width: 200px;
background-color: #f00;
}
.table .center {
background-color: green;
}
.table .right {
width: 200px;
background-color: #ff0;
}
- Grid
.grid {
display: grid;
width: 100%;
grid-template-rows: 200px;
grid-template-columns: 200px auto 200px;
}
.grid .left {
background-color: #f00;
}
.grid .center {
background-color: green;
}
.grid .right {
background-color: #ff0;
}
防抖 截流
- 防抖是在一段时间后执行操作 如果在这段时间内又触发了操作 则重新计时
- 检验邮箱是否已存在,只需要停止输入300毫秒检验一次
- 搜索匹配
- 截流就是滚动查看是否触底,本来滚动每一帧都触发,但是你限制它300毫秒查一次,减少查询次数
- 窗口resize
- 这两个都是函数里记录了timer返回了一个函数,返回的函数里用了timer变量
如何做优化
- 删除不必要的代码和注释,最小化文件
- 结合http缓存文件
- 避免使用 CSS 表达式(例如:calc())。
- 避免设置多层内联样式。
- 避免频繁操作dom
- 使用图片懒加载,让一些不可视的图片不去加载,避免一次性加载过多的图片导致请求阻塞
- 利用事件委托,减少事件注册,JS事件冒泡机制把原本需要绑定在子元素的响应事件(click、keydown……)委托给父元素,让
- 防抖节流
- webpack模块打包和JavaScript 压缩(如gzip压缩)
- 利用CDN
- 按需加载资源
- 缓存优化
- 避免重定向
- 启用 HTTP/2
- 图片编码优化,尽量使用svg和字体图标
es6用了哪些
- let const var区别
- Var声明变量的话存在变量提升,但是let和const不存在变量提升
- Let、const都是块级局部变量,但是const在声明的时候必须赋值,并且声明后不能再修改,如果声明的是复合类型,是可以修改其属性的
- 同一作用域下的let、const不能声明同名变量,但是var可以
- 箭头函数
- 箭头函数都是匿名函数
- 而且箭头函数不能作为构造函数,不能使用new
- 箭头函数中 this的指向也不相同,箭头函数本身不创建this,但是它在声明时可以捕获其所在上下文的this供自己使用,并且this一旦被捕获,就不会再发生变化,任何方法都改变不了其指向,包括call,apply,bind
- 箭头函数不绑定arguments,用rest参数…解决
- 箭头函数没有prototype原型对象
- promise
- Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的信息,并且承诺过一段时间后返回一个结果,promise有三种状态 ,pending、fulfilled,rejected,状态一旦改变,就不会再变
- Promise可以解决回调地狱的问题,并且可以支持多个并发请求,获取并发请求中的数据,promise可以解决异步的问题,但promise本身不是异步的。
- Promise对象接收一个函数作为参数,该回调函数接收两个参数,分别是resolve和reject
- Promise本身和原型链上有很多方法,比如then、catch、reject、resolve、all、race、finally等,
- then方法可以接受2个参数,分别为onfulfilledcallback和onrejectedcallback,分别为成功和失败状态后执行的回调函数
- All方法是传递一个数组,返回一个新的promise实例,这个新实例的成功或者失败,取决于数组中每一个promise实例的成功与失败,只要有一个是失败的,新的promise实例就是失败,只有所有都成功,新的promise实例才是成功的,且返回结果的顺序和参数的顺序相同
- Race也是传递一个数组,但是最新知道状态的promise实例,决定了返回的新promise 实例是成功还是失败
- 展开运算符…
- set:类数组,成员值唯一,Set 是一个构造函数,需要 new
- map: 键值对的合集,键的范围不限于字符串
setState同步异步
- 更新数据是一个异步操作
- 不能在 render 中触发 setState
- 只在合成事件和钩子函数中是异步的,原生事件和 settimerout 中是同步的
- 在 setState 函数中,会根据一个变量 isBatchingUpdates 判断是直接更新 this.state 还是放到队列中延时更新,默认是 false,但当 react 调用事件处理函数之前会先调用 batchedUpdates 将 isBatchingUpdates 修改为 true,这样 setState 就不会同步更新 this.state
filber
React Fiber是对核心算法的一次重新实现
跨域
- jsonp的原理就是利用script标签没有跨域限制,通过script标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。
- Access-Control-Allow-Origin
- 服务端设置 cors
- 普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置
- 简单请求就是head get post就是简单请求复杂,复杂请求就是单独设置了header。然后或者是其他的像delete put这些也都是复杂请求
- 复杂请求就是会有一个,那个预检就是options请求
- 所以设置了那个cors以后,还要让服务端允许options请求,要给options请求返回一个200成功。
- 需注意的是:由于同源策略的限制,所读取的cookie为跨域请求接口所在域的cookie,而非当前页。如果想实现当前页cookie的写入,nginx反向代理中设置proxy_cookie_domain 和 NodeJs中间件代理中cookieDomainRewrite参数的设置。
- postMessage跨域
- nginx代理跨域,实质和CORS跨域原理一样,通过配置文件设置请求响应头Access-Control-Allow-Origin...等字段。
- nodejs中间件代理跨域
- document.domain + iframe跨域
- 两个页面都通过js强制设置document.domain为基础主域,就实现了同域
- location.hash + iframe跨域
- window.name + iframe跨域 https和http的不同
http2.0有没有了解
缓存都有哪些 blog.csdn.net/gongch0604/… 怎么判断数据类型
怎么做拷贝
浅拷贝的意思就是只复制引用,而未复制真正的值。
怎么做深拷贝
- 深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。
JSON.parse(JSON.stringify(obj))
但是如果obj里有时间对象 regexp或者error等,会丢东西
function _cloneDeep(obj) {
// 传递进来的如果不是对象,则无需处理,直接返回原始的值即可(一般Symbol和Function也不会进行处理的)
if (obj === null) return null;
if (typeof obj !== "object") return obj;
// 过滤掉特殊的对象(正则对象或者日期对象):直接使用原始值创建当前类的一个新的实例即可,这样克隆后的是新的实例,但是值和之前一样
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Date) return new Date(obj);
// 如果传递的是数组或者对象,我们需要创建一个新的数组或者对象,用来存储原始的数据
// obj.constructor 获取当前值的构造器(Array/Object)
let cloneObj = new obj.constructor();
for (let key in obj) {
// 循环原始数据中的每一项,把每一项赋值给新的对象
if (!obj.hasOwnProperty(key)) break;
cloneObj[key] = _cloneDeep(obj[key]);
}
return cloneObj;
}