2019面试总结
一、 this指向问题
- 全局环境:(严格模式和非严格模式)
- 浏览器环境: window
- node 环境: global
- 函数上下文:
- 非严格模式
this指向window - 严格模式
this指向undefined(严格模式)
- 非严格模式
- 对象中的this
this指向调用函数的对象 - 构造函数中的this
this指向实例对象 - call&apply(call,其他参数是字符串,apply第二个参数是数组)
其函数内部的this值可绑定到 call() & apply() 方法指定的第一个对象上, 如果第一个参数不是对象,JavaScript内部会尝试将其转换成对象然后指向它。 - Bind
通过bind方法绑定后, 函数将被永远绑定在其第一个参数对象上, 而无论其在什么情况下被调用。
bind 返回的是函数,必须调用才能被执行 - Dom 事件中的this
指向的是dom 元素 - 箭头函数中的this
他会捕获其所在的上下文的this,作为自己的this值
闭包
闭包指的是:能够访问另一个函数作用域的变量的函数(函数的嵌套)
优点:防止全局变量污染
缺点:造成内存泄漏
继承
- 六种继承方式
https://www.cnblogs.com/Grace-zyy/p/8206002.html -
常用的继承方式
image.png
原型链继承,构造函数继承,组合继承
组合继承子类原型上也有父类的属性和方法
http和https
Http与Https的区别
1、https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。(原来网易官网是http,而网易邮箱是https。)
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的。Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)
可拓展,https的对称加密和非对称加密过程
子网掩码
dns
域名系统是互联网的一项服务,他作为将域名和ip地址相互映射的一个分布式数据库,能够使人更方便的访问互联网
mysql
创建表
create table tab_new like tab_old
- insert
- select
- delete
- add
https://www.cnblogs.com/zhuyongzhe/p/7686098.html
混合开发遇到的问题
卡顿,版本控制
git 提交忽略文件
.gitignore
webpack打包工具
Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
职业规划
event 有什么属性,可以用来干什么
- x
- y
- type ,事件类型
- clientX
- clentY
- screenX,screenY
- pageX,pageY
- target,srcElement
- stopProPropagation()
- preventDefault()
- keycode
- altKey
- ctrlKey
svn
开发流程
计算机组成原理
线程和进程
!!!!以下有问题
generator * yield,生成器
iterator遍历器
遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
2、Iterator的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。
3、在ES6中,有些数据结构原生具备Iterator接口(比如数组),即不用任何处理,就可以被for...of循环遍历,有些就不行(比如对象)。原因在于,这些数据结构原生部署了Symbol.iterator属性(详见下文),另外一些数据结构没有。凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。
原型链
浏览器打开一个网站登录了,再打开另外一个窗口也能登录吗,为什么
vue 路由的实现原理
hash,history实现原理,手动修改路由,页面会不会变
mvvm
生命周期函数,各生命周期代表了什么意思,分别会进行什么操作
- brforeCreate,vue实例被创建前
- created,vue实例被创建
- befordMount,vue实例被挂载前
- mounted,挂载到真实的dom节点
- beforeUpdate,数据更新之前
- updated,如果data中的数据改变就会触发对象组件的重新渲染
- beforeDestory
- destoryed,实例销毁
路由导航,前端验证token
image.png什么时候用原生端开发比较好,什么时候用h5 开发比较好
- 原生端的页面运行速度快,比较流畅
- H5页面的很多交互都没有原生的好,比如弹层、输入时候的页面滑动 等。H5的效果相对比较low,没有原生的好看,也没有原生默认的动画等效果。
- 原生APP修改页面要重新发布,等待审核(现在iOS的审核速度已经提高到1天到2天)。
H5页面的修改 可以随时上线,不用等待审核 - H5跨平台,iOS和android需要各自开发。相对原生,H5开发成本低。
- 原生APP能很好的使用设备底层功能,如摄像头、方向传感器、重力传感器等。H5有所限制。
- H5过度依赖于网络,网络不好的时候卡到不行,并且刚打开看到的都是一个空白页面。
默认的H5页面每次打开都会重新请求页面(可以做缓存,不过基本很少有做的)。
H5比原生更费流量,H5除了加载html还要加载js、css这些资源文件,相比原生网络加载速度慢。
核心需求 要用原生,比如淘宝里的产品详情页、订单页、支付页等。
非核心需求 可以考虑用H5,遇到功能调整,可以快速发布。比如淘宝首页的特色好货、热门市场等栏目 需要经常变动,用H5来做比较灵活。
2、阶段性的营销活动页面,特别是功能、布局等经常需要修改的需求,可以用H5来做。比如节日的有奖活动页面,经常需要调整,用H5做会更灵活。
APP原生和H5页面如何分辨
- 新打开页面,如果页面是个空页面,基本就是H5页面。原生的页面一般都会有一些控件提前放在页面中。
- 关闭网络后,如果是整个的空白页,这个基本就是H5页面。如何页面还有控件基本就是原生的。
- 下拉刷新的时候H5会有一个明显的刷新现象,比如闪现、导航栏标题消失等。
原生的下拉刷新没有明显现象,很平滑。 - 如果开发人员没有禁用掉WebView的长按手势,会弹出一个系统默认的快捷菜单:拷贝、查询、添加、分享。这个页面就是H5页面。
- 如果打开一个页面顶部有个进度条,就是H5页面。当然很多H5页面也没有加进度条。
- 页面的底部导航 在上拉的时候 如果跟着一起滚动,就是H5页面
get和post 区别
- 传送方式:get通过地址栏传输,post通过报文传输(请求体中)
- 传送长度:get参数有长度限制(受限于url长度),而post无限制
- 编码类型,get,application/x-www-form-urlencode
post,application/x-www-form-urlencode 或multipart/form-data - GET和POST还有一个重大区别,简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包
长的说:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
部分浏览器有区别,fireFox就发一个包
慕课网:
- get在浏览器回退是无害的,而post会再次提交请求
- get产生的url地址可以被收藏
- get请求会被浏览器主动缓存
- get请求只能进行url编码,而post支持多种编码
- get请求参数会被完整的保留在浏览器历史记录中
- get请求在url中传送的长度有限制
- get请求通过url传递参数,post 放在请求体中
observer 如何添加set和get方法,需要的添加
php.cn/js-tutorial-396048.html
虚拟dom原理
https://www.jianshu.com/p/af0b398602bc
tcp三次握手,四次牵手
https://blog.csdn.net/qq_38950316/article/details/81087809
0.1+0.2>0.3原因
js中的数字都是用浮点数表示的,并规定使用IEEE 754 标准的双精度浮点数表示。
IEEE 754 规定了两种基本浮点格式:单精度和双精度。
IEEE单精度格式具有24 位有效数字精度(包含符号号),并总共占用32 位。
IEEE双精度格式具有53 位有效数字精度(包含符号号),并总共占用64 位。
函数提升和变量提升, 域
https://www.cnblogs.com/oxiaojiano/p/7918967.html
由此可见函数提升要比变量提升的优先级要高一些,且不会被变量声明覆盖,但是会被变量赋值之后覆盖。
宏任务微任务
宏任务:setTimeout,setInterval,script,setImmediate,requestAnimationFrame
微任务:process.nextTick,Promise.then catch finally,MutationObserver
lodash的get方法
https://segmentfault.com/a/1190000015605531
职业规划
多学习前端方面的技术,拓展深度和广度,期望是学习到原理层面
做过什么是印象深刻的,最有成就感的
pk对战项目,开发时间只有1周,性能要求较高,复杂度也较高
平时都看什么书,有关技术的
大学什么科目比较好,说3个
cookie中都有什么
好未来都三个优点和缺点
- 技术氛围好
- 用的技术比较新
- 开发流程清晰
什么比较好,原生js,vue
性能优化
https://www.cnblogs.com/qcloud1001/p/7561498.html
https://www.cnblogs.com/lanxiansen/p/10972802.html
- 减少请求资源大小或者次数
http 协议
http 协议的特点:简单,灵活,无连接,无状态
http报文的组成部分
- 请求报文
请求行,请求头,空行,请求体 - 响应报文
状态行,响应头,空行,响应体
http方法
- get,获取资源
- post,传递资源
- put,更新资源
- delete,删除资源
- head,获得报文首部
http状态码
- 1xx,指示信息,表示请求已接收,继续处理
100 客户端可以继续
101 指示服务器正根据 Upgrade 头切换协议 - 2xx,请求成功,表示请求已被成功接受
200 请求正常成功
201 指示请求成功并在服务器上创建了一个新资源
202 指示已接受请求进行处理但处理尚未完成
203 指示客户端呈现的元信息并不源自服务器
204 指示请求成功但没有返回新信息
205 指示代理应该 重置导致请求被发送的文档视图
206 指示服务器已完成对资源的部分 GET 请求 - 3xx,重定向,要完成请求必须进行更进一步的操作
300 请求的资源对应于表示形式集合中的某种表示形式,每种表示形式都有自己的特定位置
301 指示已经将资源永久地移动到了某个新位置,并且将来的引用应将新 URI 用于其请求
302 指示已经将资源暂时地移动到了另一个位置,但将来的引用仍应使用原来的 URI 访问该资源。 保留此定义是为了向后兼容。SC_FOUND 现在是首选定义
303 指示可在另一个 URI 之下找到该请求的响应
304 指示条件 GET 操作发现资源可用但不可修改,原来缓存的文档还可以用
305 指示必须 通过 Location 字段给定的代理访问请求资源
307 指示请求的资源暂时驻留在另一个 URI 之下。临时 URI 应该 通过响应中的 Location 字段提供 - 4xx,客户端错误,请求有语法错误或者请求无法实现
400 指示客户端发送的请求在语法上不正确
401 指示请求需要进行 HTTP 验证
402 保留此代码以备将来使用
403 指示服务器理解请求但拒绝完成它
404 指示请求的资源不可用
405 指示 Request-Line 中指定的方法不支持 Request-URI 标识的资源
406 指示请求标识的资源只能生成响应实体,根据请求中发送的 accept 头,这些响应实体具有不可接受的内容特征
407 指示客户端必须 首先通过代理验证其自身
408 指示客户端没有在服务器准备等待的时间内生成请求
409 指示由于与当前资源状态冲突请求无法完成
410 指示资源在服务器上不再可用并且不知道转发地址。应该 认为此条件是永久性的
411 指示在没有定义 Content-Length 的情况下无法处理请求
412 指示在服务器上测试一个或多个请求头字段中给出的前提时,该前提被求值为 false
413 指示因为请求实体大于服务器愿意或能够处理的实体,所以服务器拒绝处理请求
414 指示因为 Request-URI 的长度大于服务器愿意解释的 Request-URI 长度,所以服务器拒绝为请求提供服务
415 指示因为请求实体的格式不受请求方法的请求资源支持,所以服务器拒绝为请求提供服务
416 指示服务器无法服务于请求的字节范围
417 指示服务器无法服务于请求的字节范围 - 5xx,服务器错误,服务器未能实现合法请求
500 指示 HTTP 服务器内存在错误使服务器无法完成请求
501 指示 HTTP 服务器不支持完成请求所需的功能
502 指示 HTTP 服务器在充当代理或网关时从它参考的服务器接收到一个无效响应
503 指示 HTTP 服务器暂时过载,并且无法处理请求
504 指示服务器在充当网关或代理时没有从上游服务器接收到及时的响应
505 指示服务器不支持或拒绝支持请求消息中使用的 HTTP 协议版本
持久连接
http有普通模式和keep-alive模式
普通模式:每个请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开连接
持久连接模式:使客户端到服务器端的连接持续有效,当出现对服务器的后续请求时,keep-alive功能避免了建立或者重新建立连接1.1支持
管线化
请求1-》请求2-》请求3-》响应1-》响应2-》响应3
把请求打包,响应打包
- 管线化机制通过持久连接完成,仅http/1.1支持此技术
- 只有get和put支持管线化,post有限制
- 初次建立连接,不应使用管线化机制,因为对方不一定支持http/1.1协议
- 管线化不会影响响应到来的顺序
- http/1.1要求服务端支持管线化,并不要求服务端也对响应做管线化处理只是要求对于管线化的请求不失败即可
outline,shadow
- outline (轮廓)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。
- box-shadow,box-shadow 属性向框添加一个或多个阴影。
div
{
box-shadow: 10px 10px 5px #888888;
}
css实现三角形
https://www.cnblogs.com/linsinan/p/6928734.html
border-width
不需要的边设置成透明
.box
{
width:0px;
height:0px;
border-top:50px solid rgba(0,0,0,0);
border-right:50px solid rgba(0,0,0,0);
border-bottom:50px solid green;
border-left:50px solid rgba(0,0,0,0);
}
css如何开启硬件加速
.cube {
-webkit-transform: translate3d(250px,250px,250px)
rotate3d(250px,250px,250px,-120deg)
scale3d(0.5, 0.5, 0.5);
}
.cube {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
/* Other transform properties here */
}
https://www.jb51.net/css/572687.html
盒模型
https://www.cnblogs.com/chengzp/p/cssbox.html
IE盒模型 width= content+ padding+ border
标准盒模型 width= content+ padding+ border
设置两种盒模型
box-sizing:content-box; width就是content
box-sizing:border-box, width
js 获取宽高
- dom.style.width/height ,这种方式只能取到dom元素内联样式所设置的宽高,也就是说如果该节点的样式是在style标签中或外联的CSS文件中设置的话,通过这种方法是获取不到dom的宽高的。
- dom.currentStyle.width/height (IE), 这种方式获取的是在页面渲染完成后的结果,就是说不管是哪种方式设置的样式,都能获取到。
但这种方式只有IE浏览器支持。 - window.getComputedStyle(dom).width/height(标准), 这种方式的原理和2是一样的,这个可以兼容更多的浏览器,通用性好一些。
- dom.getBoundingClientRect().width/height
这种方式是根据元素在视窗中的绝对位置来获取宽高的 - .dom.offsetWidth/offsetHeight
bfc解决的问题
https://www.cnblogs.com/chengzp/p/cssbox.html
怎么取创建bfc
- float属性不为none(脱离文档流)
- position为absolute或fixed
- display为inline-block,table-cell,table-caption,flex,inine-flex
- overflow不为visible
- 根元素
应用场景
- 自适应两栏布局
- 清除内部浮动
- 防止垂直margin重叠
- 避免某元素被浮动元素覆盖
- 避免多列布局由于宽度计算四舍五入而自动换行
垂直居中
- flex布局
justify-content: center; /子元素水平居中/
align-items: center; /子元素垂直居中/
display: -webkit-flex; - 定位+transflom
vue两大特点
- 数据驱动视图
- 组件化
v-if v-show
v-show只是在修改元素的css样式,也就是display的属性值,元素始终在Dom树上
v-if是根据后面数据的真假值判断直接从Dom树上删除或重建元素节点
H5调试
- h5 调试方式
charles 抓包
抓包流程- 手机端无线后边的感叹号配置代理服务
- ip:电脑的ip,端口号8888
-
手机安装电脑charles 的证书
image.png
image.png
手机访问 chls.pro/ssl地址即可下载安装
-
代理本地代码
image.png
image.png
通过配置charles的Map Remote
访问gamma 环境时,代理到 127.0.0.1:8080
!!注意: 另外http协议的默认端口是80;https协议的默认端口是443
debug版的包可以连接电脑直接在电脑调试
- ios debug版的包,可以连上手机数据线在safari 中调试
- android,chrome://inspect/#devices
可在chrome中调试,需翻墙
vue实现复用
- 组件封转
- vuex
- 自定义指令
- 引入对象或者方法
数组中有对象如何实现快速去重
- equal
- 转成字符串判断相等
有什么要问他
git stash,获取暂存内容
- git stash // 隐藏分支工作现场,为修复bug准备
- git stash list // 查看有哪些分支隐藏的工作现场,为恢复工作现场做准备
- git stash apply // 恢复工作现场,但不删除存储的stash内容,结合git stash drop进行删除
- git stash drop // 删除存储的stash内容,恢复到隐藏前的工作现场
- git stash pop // 恢复到隐藏前的工作现场,相当于git stash apply和git stash drop
- git stash apply stash@{0} // 可以多次stash,通过git stash list查看所有的stash,然后可以恢复到指定的隐藏的工作现场
git reset和git revert
https://blog.csdn.net/yxlshk/article/details/79944535
- git reset 回退到某个版本,之前的版本就不见了,git push时需要强推
- git revert,又生成一个新的版本,在后面之前的所有版本还在
改变this指向问题
https://www.cnblogs.com/web-chuan/p/9096356.html
- call,apply
- bind
- new
- 可以使用局部变量来代替this指针
var _this = this; - return
在构造函数的时候,使用return进行返回一个Object的时候,当去new一个实例对象的时候,会将this指向改变为return的Object;
????
防抖,节流
防止抖动和防止节流
应用场景,控制用户点击次数
滚动时,进行复杂数据处理或者样式变化
// 防止节流,每隔wait时间内执行一次(将多次执行变成每隔一段时间执行)
function text(){
console.log(111)
}
function throttle(fn,wait,immediate){
var timer=null;
return function(){
var args = arguments
if(immediate) {
fn.apply(this, args);
immediate = false;
}
if(!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, wait);
}
}
}
$("#throttle").click(throttle(text,2000,true))
// 防止抖动,将多次执行变成最后一次执行
function demo(){
console.log(222)
}
function debounce(fn, wait, immediate){
var timer = null;
return function(){
var args = arguments
if(immediate) {
fn.apply(this, args);
immediate = false
}
clearTimeout(timer)
timer = setTimeout(function(){
fn.apply(this, args);
},wait)
}
}
$("#debounce").click(debounce(demo,2000,true))
控制500ms 内scroll 只触发一次,触发时计算当前滚的位置,修改active样式
<template>
<div>
<Header></Header>
<div class="content container">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
<div class="mask" v-if="maskShow"></div>
<phone-preview v-if="phonePreviewData.isShow" :urlData="phonePreviewData"></phone-preview>
</div>
</template>
<script>
import Header from './header'
import ucenter from '../../ucenter/config'
import phonePreview from '../personalShow/phonePreview.vue'
export default {
components: {
Header,
phonePreview,
},
data() {
return {
// isCollapse: false, // 控制左侧菜单折叠
maskShow:false,
phonePreviewData:{},
};
},
mounted(){
let box = document.getElementsByClassName('container')[0];
box.addEventListener('scroll', this.scrollThrottle(this.onScrollHandler, 5000, true));
this.$bus.$on("maskShow",(data)=>{
this.maskShow = data;
})
this.$bus.$on("phonePreview",(data)=>{
this.phonePreviewData = data;
})
},
methods:{
onScrollHandler(e) {
console.log('ceshiyixia')
// resize节流 500ms内只能触发一次
var modules = document.getElementsByClassName('module-box');
let curModules = [];
for(let i = 0; i < modules.length; i++) {
let curModule = document.getElementsByClassName(modules[i].id)[0];
console.log(curModule,'curModule')
curModule.classList.remove("active");
if(e.target.scrollTop > modules[i].offsetTop - 50 && e.target.scrollTop < (modules[i].offsetTop + modules[i].offsetHeight)) {
curModules.push(curModule)
curModule.classList.add("active");
} else if(e.target.scrollTop === 0) { // 滚动至顶部
modules[0].classList.add("active");
} else if(e.target.scrollTop + e.target.offsetHeight === e.target.scrollHeight) { // 滚动至底部
}
if(curModules.length > 1) {
curModules.forEach((item, index, arr) => {
if(index !== arr.length - 1) {
item.classList.remove("active");
}
})
}
}
},
scrollThrottle(fn, wait, immediate) {
let timer = null;
return function() {
let args = arguments;
if (immediate) {
fn.apply(this, args);
immediate = false;
}
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, wait);
}
}
},
}
};
</script>
git rebase
指令
promise的原理
https://www.jianshu.com/p/b4f0425b22a1
原地排序,不占用其他的内存空间
fn.sleep(10).eat()
await属于宏任务还是微任务
await后边的放到微任务中,相当于promise.then
https://www.cnblogs.com/wangxi01/p/11190608.html
console问题,作用域问题
箭头函数问题
node多线程
原生实现bind方法
cookie可以跨子域吗,cookie中 有什么
在地址栏输入url按回车键,都进行了什么操作
- DNS解析
- TCP连接,三次握手
- http协议等等可拓展https和http的区别,https的加密方式等
- 请求回来的html,浏览器如何渲染,js执行顺序,可拓展宏任务,微任务等
如何解决跨域,后端如何设置‘
- iframe
- 反向代理
- CORS
data的数据结构
如何提高用户体验和性能优化
事件流 冒泡,事件委托live.dekegete.on. 原理是冒泡
es6,set,map
用的vue版本,3.0的了解
首屏优化
js实现判断两个二叉树是否完全相同
js实现bind
js实现reduce
js实现map
vue相关,双向绑定原理,虚拟DOM远离,为什么要用key,data为什么是个方法
js实现深拷贝
js实现二分查找
vuex
new操作符具体干了什么呢?其实很简单,就干了三件事情。
var obj = {};
obj.proto = Base.prototype;
Base.call(obj);
promise
- Promise.all()并行执行异步任务
- Promise.race()获得先返回的结果即可
set,Map
- Set
1.成员不能重复
2.只有健值,没有健名,有点类似数组。
- 可以遍历,方法有add, delete,has
- weakSet
成员都是对象
成员都是弱引用,随时可以消失。 可以用来保存DOM节点,不容易造成内存泄漏
不能遍历,方法有add, delete,has
- Map
本质上是健值对的集合,类似集合
可以遍历,方法很多,可以干跟各种数据格式转换 - weakMap
1.直接受对象作为健名(null除外),不接受其他类型的值作为健名
健名所指向的对象,不计入垃圾回收机制
不能遍历,方法同get,set,has,delete