这里是我19年遇到的面试题,记录一下
函数的使用(递归,闭包啥的),函数式编程(react内容),变量的掌控(死区,提升,全局,块级),react优化的认知(减少render),游览器的认知(状态码,缓存机制),js(单线程,实现异步),html(http,https,xml),css(居中,动画)
react: 虚拟dom,diff算法,中间件,几种组件,高阶组件,受控组件,父子传值,性能优化,新知识
- 判断类型是否为字符串的方法(尽量多):
目前我觉得好用的方式,后者还可以判断数组等复杂数据类型。
扩展。判断是否为数组 :
- for in , filter, map, forEach, every, some, for of,的区别和作用
every: 返回值为true,false,全部符合才会返回true
some: 返回值为true,false,只要有一个符合就是true
filter: 返回值为过滤后的数组,长度可能改变
forEach:无返回值
map: 返回一个长度不变的数组
for in是ES5标准,遍历key.
for of是ES6标准,遍历value.
- 水平垂直居中的css写法:
重点:
当内容未知宽高:
{
display: flex;//grid也可以
align-items: center;
justify-content: center;
}
- 数字数组排序的方法:
最简单的:
arr.sort()
不能用现成的函数自己循环的话:冒泡排序
function so(arr) {
for (let i = arr.length; i > 0; i--) {
const num = arr[i]
if(arr[i] > arr[i - 1]) {
arr[i] = arr[i - 1]
arr[i-1] = num
}
}
}
//注意这是一次的冒泡
需要执行多次用,最多为长度的次数。所以补足一下为:
扩展:reduce累加,
-
position有哪些:
absolute, fixed, relative, static, sticky(新增属性,保持模块在屏幕内), inherit
跨域的解决方法 :
我的项目中,线上服务器端配置解决,本地用nginx解决。
vue的特点:
与react相比下,双向绑定,入门简单。...em...很广泛,也不知道面试官希望引导你到哪个点上,你可以往你熟悉点去说。我不太会vue,就只能简单bb几句。对最新的前端技术有没有了解
react支持包含内容的数组类型返回(已经是上上个版本了,但是也许有些人不知道,也写一下,但是最新版本我还没去看呢)数组的各种操作,头部尾部中间,插入删除
push(),pop()
shift(),unshift()
splice(1,2,2,2,2) 再下标为1的之前数上2个替换成2,2,2手写高阶组件
function geth(propsComponent) {
return
我是高阶组件
}
- 0.1 + 0.2 不等于 0.3: 由于计算机底层算法,0.1 + 0.2 进行二进制相加 不等于 0.3的二进制
- react生命周期与其作用
constructor(props) 构造 在函数内部使用this.props,必须传入props,并使用super(props): 对父类进行初始化
componentWillMount() 将要加载完成
componentDidMount() 已经加载完成
componentWillReceiveProps(nextProps) 接受到下一份数据
shouldComponentReceiveProps() 是否更新渲染
componentWillUpdate() 即将更新渲染
componentDidUpdate() 完成渲染
render() 渲染
componentWillUnmount() 将要移除
react构造的时候由父组件先,渲染完成的时候是子组件先
中间件:执行在action后reduce前,产生异步的功能。
redux-thunk(简单,可用) redux-saga(难度大,集中处理action,可实现的多)高阶组件和高阶函数的差别:
高阶函数:接受一个或者多个函数,输出一个函数,常见的map就是高阶函数
高阶组件:接受一个组件输出一个组件。
官方:a higher-order component is a function that takes a component and returns a new component
- 组件创建方法
无状态函数组件:一个函数传入props,只有一个render,不涉及state,无法使用this,无法访问生命周期。组件不会被实例化,渲染性能得到提升。
React.createClass:(ES5)自动绑定this
React.Component:(ES6)常用箭头函数绑定this,也有bind绑定的(PureComponent,控制浅比较,减少渲染次数)
扩展:无状态函数组件可做高阶组件
- 数组去重:
1.思路,创建一个空数组,遍历需要去重的数组,检查是否存在于新数组,否则push,反之不作为。
function same(arr) {
let array = []
arr.forEach(i => {
array.indexOf(i) > 0 ? null : array.push(i)
})
return array
}
2.利用es6的set
function unique5(arr){
var x = new Set(arr);
return [...x];
}
3.filter 过滤掉相同的,filter接受的函数传入三个参数,value,index,使用的数组
- 三次握手
tcp(传输控制协议)通信过程:第一次向服务器发送信息,第二次服务器收到信息向游览器发送信息,第三次游览器收到信息告诉服务器。通过三次握手,明确双方可接收可发送。
接下去就可以是数据传输。
再下面就是四次挥手:
第一次主动方告诉被动方,我要关闭了,
第二次被动方告诉主动方我知道你要关闭了
第三次被动方告诉主动方我最后的东西都发完了,不会再发了,可以关闭了。
第四次主动方告诉被动方我知道了,可以关闭了。
扩展:http和https,域名和ip地址
地址和域名是一对多的关系,地址是唯一的,但是一个地址可以有多个域名。称呼不一样了,但是实质上指向的都是唯一的那个地址。一个域名只能指向一个地址。
https是加密的http(超文本传输协议),作用的OSI(7层网络模型)层次不一样。
网页js 下载过程:
js安从上到下的顺序下载,但是有可能上一个没下载完成,下一个就开始下载了,所以可以是同时正在下载,但是执行的时候一定会保证是从上一个到下一个。
扩展:html加载过程,先下载js文件,再并行css和dom加载(因为先加载js,js文件过大会导致堵塞,页面出现滞后)es6的新特性有哪些了解
let const
promise promise.all promise. race
箭头函数
set
class super
字符串拼接
<------------以上为我使用频繁的let const 的特点和与var的区别:
var ,全局变量。存在变量提升(只提升声明,不提升值),未定义的输出会显示undefined,不报错。会影响到循环体外。重复命名不会报错。
let ,区域作用。会出现暂时性死区,未定义的使用会报错,不会影响到循环体外。一个块级内重复命名会报错。
扩展:
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[5]() //10,a[5]输出f(){console.log(i);},后面加个括号代表执行f()
解决方式var用let代替,就会输出想要的 5
另外的办法:
立即执行函数
闭包
再说说闭包:
官方:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的特点:
1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
为什么会造成内存泄漏,这里就要说一下回收机制,js存在回收的机制,当一个变量不再被使用的时候,就回收了。而闭包呢,一个函数作为返回值赋值给了a[i],那就是一直在被使用,就得不到释放。解决办法,在使用结束后,把a[i]赋值成别的。
function showNum(i) {
return function () {
console.log(i)
}
}
var a = []
for (var i = 0; i < 5; i++) {
a[i] = showNum(i)(); //循环输出1,2,3,4
}
解决刚刚的问题的闭包方式:
大环境:showNum 返回了一个函数,在showNum之外被调用,形成了闭包。
使用:闭包内没有释放资源的栈区,保持了当时的变量。
link 和 import 的区别:
import是css提供的,引入样式表,link是html提供的可以引入css,js等
import引入css是在页面加载后,link是加载前游览器有缓存怎么办
浏览器缓存分为两种,一种是强缓存,一种是协商缓存
扩展:离线储存是把游览器的缓存储存下来
缓存会造成一个游览器返回304 ,重定向。因为本来是要去服务器要的图片,判断结束了去缓存里取了
- webSocket:
建立一个双向的长时间甬道。
创建后的主要方法:
onopen
onmessage
onclose
- 一个div 100px宽度变化成200px
这个动手去试才记忆深吧...考点css3动画的2种实现方式
css3动画:
animation: mymove;//使用mymove效果
transition: width 2s;//宽度变化2秒的过渡,常和hover配合使用
transform: rotate(7deg)//旋转7度
@keyframes mymove {
from: //0%
to: //100%
}
- react优化,render a||[] 的写法避免,每次[]都进行创建一个数组,可以在构造的时候赋值给一个常量去代替,
shouldComponentReceiveProps()的控制,比如父组件A下有 !5个组件,只有一个的props改变了,但是A render的时候下面5个都重新render,改善shouldComponentReceiveProps减少render次数。 - 函数组件A , 普通组件B 使用其实是A() newB 。
4.组件的生命周期不是继承来的,只是在react中”钩到“就使用,从react继承而来语法糖<>判断成new B,函数组件没有继承react,语法糖判断为A()
5.游览器返回码:
504超时,500服务器错误,405请求方式不允许,404接口不存在,403权限不足,没登录就去请求,401登陆认证失败,400参数错误,(304,302,301)重定向,200成功
6.js异步,settimeout()为什么设置0也是最后触发,因为js是单线程的。异步的会进入到异步的堆栈里,再进入主线程。
7.箭头函数和普通函数的区别:不能new,this绑定
var a = ''
() {
console.log(a) //let导致暂时性锁死,不能使用a,报错
let a
}()
() {
console.log(a) //var 导致变量提升,undefined
var a
}()
1.深拷贝,浅拷贝,
浅拷贝:
var a = {b: 1}
var c= a
c.b = 2
a //{b: 2}
DNS:域名解析,返回域名所对应的ip,CND, http:80端口, https:443端口,加密传输, tcp
JSONP 原理: <\script>是不存在跨域问题的的,jsonP利用这个原理做了跨域请求,动态的以<>的形式引入下载好的json文件。
清除浮动:1.zoom:1 2.clean:both,3.给父级宽高4.overflow:hidden
webSocket: 一个TCP协议
hasLayout:是否继承祖先的一些属性,ie问题的高发区,为true的时候必须自己去设置自己的内容大小。IE6以及一下特有属性
响应式,自适应:媒体查询,
兼容性:各种内核
1、IE浏览器内核:Trident内核,也是俗称的IE内核;
2、Chrome浏览器内核:统称为Chromium内核或Chrome内核,以前是Webkit内核,现在是Blink内核;
3、Firefox浏览器内核:Gecko内核,俗称Firefox内核;
4、Safari浏览器内核:Webkit内核;
5、Opera浏览器内核:最初是自己的Presto内核,后来是Webkit,现在是Blink内核;