一.杭州知衣科技
1.js数据类型
1)基本数据类型(6种)
number
string
boolean
null
undefined
Symbol(es6):创建一个独一无二的标识
bigInt(谷歌67版本)
2)引用数据类型(4种)
1.Object(function、Array、Date)
1)Array
数组类型的检测
1)instanceof
arr instanceof Array
2)Array
Array.isArray(arr)
3)isPrototypeOf
Array.prototype.isPrototypeOf(arr)
4)obj.__proto__ === Array.prototype;
通过原型链做判断
5)Object.prototype.toString.call([])
2.深拷贝和浅拷贝的区别
1)深拷贝:两个对象完全相同,但是重新开辟一块内存空间,指向不同的内存空间,修改一个对象的属性,不会改变另一个对象的属性
实现深拷贝:
1._.cloneDeep()
let _ = require('lodash');
let obj2 = _.cloneDeep(obj1);
2.jQuery.extend()
let $ = require('jquery');
let obj2 = $.extend(true, {}, obj1);
3.JSON.stringify()
let obj2=JSON.parse(JSON.stringify(obj1));
存在弊端,会忽略undefined、symbol和函数
4.递归拷贝
function deepClone(arr){
先判断数组的类型
var obj=arr.constructor==Array?[]:{};
for(var item in arr){
if(typeof arr[item]==="object"){
obj[item]=deepClone(arr[item]);
}else{
obj[item]=arr[item];
}
}
return obj;
}
2)浅拷贝:浅拷贝只拷贝一层。基本数据类型拷贝的是值; 引用数据类型拷贝的是内存地址,简单的地址值的复制
实现浅拷贝:
1.Object.assign
let newObj = Object.assign({}, obj);
1)对象的合并; 2)如果对象存在嵌套关系,进⾏浅拷⻉
2.arr.slice(0)
let newArr = arr.slice(0)
3.arr.concat()
let newArr = arr.concat()
concat功能:数据项的简单一个层次的拼接
4.使用拓展运算符实现的复制
let newArr = [...arr]
3.如何实现一个对象的深拷贝?
1)_.cloneDeep()
let _ = require('lodash');
let obj2 = _.cloneDeep(obj1);
2)jQuery.extend()
let $ = require('jquery');
let obj2 = $.extend(true, {}, obj1);
3)JSON.stringify()
let obj2=JSON.parse(JSON.stringify(obj1));
存在弊端,会忽略undefined、symbol和函数
4)递归拷贝
function deepClone(arr){
先判断数组的类型
var obj=arr.constructor==Array?[]:{};
for(var item in arr){
if(typeof arr[item]==="object"){
obj[item]=deepClone(arr[item]);
}else{
obj[item]=arr[item];
}
}
return obj;
}
4.如何实现数组的清空?
1)arr.splice(0,arr.length)
2)arr.length=0
3)赋值为一个空数组:arr=[]
5.数组去重的方法?
1)es6的Set方法:let newArr=[...new Set(arr)]
2)利用数组的indexOf下标属性:
let arr=[1,3,5,2,4,3,6]
let newArr=[]
for(let i = 0; i<arr.length; i++){
if(newArr.indexOf(arr[i])==-1){
newArr.push(arr[i])
}
}
console.log(newArr)
3)利用数组原型上的includes方法
if(!newArr.includes(arr[i])){
newArr.push(arr[i])
}
4)将数组的每一个元素依次与其他元素做比较,发现重复元素,利用数组的splice()方法删除重复元素。
let arr=[1,3,5,2,4,3,6]
for(var i=0;i<arr.length-1;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){
arr.splice(j,1);
j--;
}
}
}
console.log(arr)
5)先将原数组排序,再与相邻的进行比较,如果不同则存入新数组。
6)利用数组原型对象上的 filter 和 includes方法。
7)利用数组原型对象上的 forEach 和 includes方法。
8)利用数组原型对象上的 lastIndexOf 方法。
6.事件捕获与事件冒泡,事件委托?
从页面中接收事件的顺序:
1)事件捕获:不太具体的节点更早接收事件,具体的节点到最后接收事件。
2)事件冒泡:事件开始由最具体的元素接收,然后逐级向上传播到不具体的节点
3)事件委托:将事件绑定当前元素的父元素上,点击当前元素时,就会执行父元素上绑定的事件处理函数
通过监听一个父元素,来给不同的子元素绑定事件,减少监听次数,从而提升速度。
7.CSS实现响应式布局?
响应式:一个网站能够兼容多个终端
特点:1.同时适配PC + 平板 + 手机等
2.标签导航在接近手持终端设备时改变为经典的抽屉式导航
3.网站的布局会根据视口来调整模块的大小和位置
1)@media媒体查询:
原理:通过媒体查询@media,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局
2)百分比 %:
比如当浏览器的宽度或者高度发生变化时,通过百分比单位,
可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果
3)vw/vh:与百分比布局类似
vw表示相对于视图窗口宽度,vh表示相对于视图窗口高度。任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一
4)rem:相对于根元素html的font-size属性。针对不同设备分辨率改变font-size的值
5)第三方库,如:bootstrap、element ui、antd提供的栅格布局实现响应式
二.北京易商迅达科技有限公司
1.双向数据绑定?
model => view 以及 view => model 的双向绑定
把Model绑定到View,JS代码更新Model时,View就会自动更新;
用户更新了View,Model的数据也自动被更新了
1.双向绑定由三个重要部分构成:MVVM
1)数据层(Model)
2)视图层(View)
3)业务逻辑层(ViewModel):将数据与视图关联起来
2.ViewModel的功能:1)数据变化后更新视图
2)视图变化后更新数据
3.ViewModel的两个主要部分:1)监听器(Observer):对所有数据的属性进行监听
2)解析器(Compiler):对每个元素节点的指令进行扫描跟解析,根据指令模板替换数据,以及绑定相应的更新函数
4.流程:1)new Vue()首先执行初始化,对data执行响应化处理,这个过程发生Observe中
2)同时对模板执行编译,找到其中动态绑定的数据,从data中获取并初始化视图,这个过程发生在Compile中
3)同时定义⼀个更新函数和Watcher,将来对应数据变化时Watcher会调用更新函数
4)由于data的某个key在⼀个视图中可能出现多次,所以每个key都需要⼀个管家Dep来管理多个Watcher
5)将来data中数据⼀旦发生变化,会首先找到对应的Dep,通知所有Watcher执行更新函数
2.组件通信
1)父子组件之间的通信
1.props / $emit
1)父组件通过props向子组件传递数据:子组件的数据会随着父组件不断更新。
2)子组件通过$emit和父组件通信:$emit绑定一个自定义事件,当这个事件被执行时就会将参数传递给父组件,而父组件通过v-on监听并接收参数。
2.ref / $refs
1)在子组件上,ref的引用指向了子组件的实例。可以通过实例来访问组件的数据和方法。
2)父组件中通过this.$refs来访问
2)兄弟组件之间的通信
1.EventBus
使用场景:兄弟组件传值
创建一个中央事件总线EventBus
兄弟组件通过$emit触发自定义事件,$emit第二个参数为传递的数值
另一个兄弟组件通过$on监听自定义事件
2.$parent 或$ root
通过共同祖辈$parent或者$root搭建通信桥连
兄弟组件:this.$parent.on('add',this.add)
另一个兄弟组件:this.$parent.emit('add')
3)祖孙与后代组件之间的通信
1.$attrs 与$ listeners
使用场景:祖先传递数据给子孙
设置批量向下传属性$attrs和 $listeners
包含了父级作用域中不作为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。
可以通过 v-bind="$attrs" 传⼊内部组件
2.provide 与 inject
祖先组件通过provide发送传递的值
后代组件通过inject接收值
4)复杂关系的组件间通信
Vuex作用相当于一个用来存储共享变量的容器
3.input输入框的内容发生改变后台怎么知道?
监听
三.通联支付
1.element-ui样式的二次封装?
只简单的做过属性,方法,事件的使用
2.echarts,antv怎么使用的?
dashboard(数据可视化)有很多窗口,大致分为三行四列,伸缩盒布局自适应内容填充。
主要运用echarts,antv填充内容。在methods中写myChart方法:data存放数据。折线图,条形图等xField,yField有横轴坐标。饼图有angleField角度。
缺点:图表的波动是根据自己每天去食堂吃饭,用感官判断的。自己精力有限,另外项目周期比较短,没有统计真实数据。
3.浏览器的兼容性问题
不仅仅是IE浏览器
1.浏览器默认样式
问题:有些浏览器有默认样式,不同浏览器样式不同,
导致我们布局的页面在不同浏览器发生错乱
解决:清除默认样式,保证在每个浏览器样式统一
body{/*清除body自带的间隔和填充*/
margin:0px;
padding:0px;
}
* {/*清除所有标签的间隔和填充*/
margin: 0px;
padding: 0px;
}
ul{
list-style:none;
}
2. 图片问题
1)img标签底部间隙问题
问题:div中包含一张图片,底部有间隙
解决:1.将图片的垂直对齐方式vertical-align,设为top或者bottom
2.将图片转换为块元素display:block
3.将包含图片的父容器的字体大小设置为0,font-size:0
4.标签中无空格等
2)img标签IE下图片有边框
问题:图片加了超链接之后产生蓝色边框(IE6~10)
解决:
img{
border:none;
}
3.margin上下边框合并问题
问题:1.当相邻元素都设置了 margin 边距时,margin 将取最大值,舍弃小值
2.双倍边距:设置浮动,同时又设置margin-left
解决:1.只给一个容器调整外边框的间隔即可,不要同时给两个
2.给浮动的元素指定display:inline;
4.列表前设置图片,图片与后面文字对齐问题
解决:采用背景定位和字符缩进
background:url() no-repeat left center;
text-indent:16px;
5. 除去滚动条的问题
问题:隐藏滚动条
解决:1.只有ie6-7支持
2.除ie6-7不支持 body{}
3.所有浏览器 html{overflow:hidden}
6.高度问题
问题:如果设定了高度,内容过多时,ie6下会自动增加高度、其他浏览器会超出边框
解决: 设置overflow:hidden;
4.vue使用的功能点
全局前置守卫放在哪个页面?main.js
登录功能:在登录页面,设置全局前置守卫beforeEach,
设置白名单,login/register
判断有没有token,如果token不存在就留在login页面,token存在就next()跳转到home页面
四.中电太极
1.功能,最满意的项目。为什么会做这个项目?
2.vuex?刷新后初始化,登录者的信息不能只保存在vuex中。
保存在localStorage和sessionStorage,两者的区别?
1.localStorage:本地存储。使用localStorage存储数据,即使关闭浏览器,也不会让数据消失,除非主动的去删除数据
2.sessionStorage:会话存储。只存在一个会话中。生命周期是在浏览器关闭前。
区别:
1)数据有效期限不同,sessionStorage仅在当前浏览器窗口关闭之前有效;
localStorage始终有效,窗口或者浏览器关闭也一直保存;
2)作用域不同:sessionStorage不能在不同的浏览器窗口中共享,即使不在同一个页面;
localStorage在所有同源窗口共享。
3.常用的生命周期?
created: 实例创建完成,初始化某些属性值,然后再渲染成视图。
mounted: 组件挂载到实例后,初始化页面完成,对html的dom节点进行一些操作。
4.es6新特性
1)变量声明:let和const。不能重复声明,没有变量声明提升,有块级作用域
2)箭头函数就是函数的一种简写形式
3)对象,数组解构:使用模式匹配方式从一个对象,数组中快速获取值的方式
4)扩展运算符和rest参数:右拆分; 左聚集
扩展运算符⽤于将数组中的元素拆分出来;
rest参数是拓展运算符的逆运算
5)for...of 和 for...in
for...of 用于遍历一个迭代器
for...in 用来遍历对象中的属性
6)新增的数据结构:Set,Map
7)异步的解决方案:1.promise:
2.generator:1)可以控制函数的执行。yield暂停函数,next方法启动,每次返回的是yield后的表达式结果。
2)Generator 函数是一个状态机,封装了多个内部状态。
Generator 函数除了状态机,还是一个遍历器对象生成函数。
3)yield表达式本身没有返回值,或者说总是返回undefined。
next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
3.async:
5.弹性布局
当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式
注意,设为flex布局后,子元素的float、clear和vertical-align属性将失效。
1)6个属性设置在容器上:
flex-direction:主轴的方向
flex-wrap:换行。
flex-flow:flex-direction和flex-wrap的简写,默认值为row nowrap。
justify-content:主轴的对齐方式
align-items:交叉轴的对齐方式
align-content:多根轴线的对齐方式
2)3个属性设置在子元素上:
flex属性是flex-grow,flex-shrink和flex-basis的简写,默认值为0 1 auto。
1.flex-grow:放大比例,默认为0
2.flex-shrink:缩小比例,默认为1
3.flex-basis:最小宽度
五.谷露软件
1.position定位布局
1)静态定位 position:static 不脱离文档流
2)相对定位 position:relative 不脱离文档流 相对于自身定位
3)绝对定位 position:absolute 脱离文档流 没有定位祖先的相对于浏览器视口左上角定位;有定位祖先的相对于定位祖先进行定位
4)固定定位 position:fixed 脱离文档流 相对于浏览器视口定位
5)粘性定位 position:sticky 不脱离文档流 没有定位祖先的相对于浏览器视口左上角定位;有定位祖先的相对于定位祖先进行定位
需要粘性定位的元素的宽度不能超过其父元素宽度,否则失效
2.盒子模型
1)标准盒子; 2)IE盒子
盒模型由四个部分组成的,margin、border、padding和content。
1.区别在于设置width和height时,所对应的范围不同:
1)标准盒子的width和height范围只包含了content,
2)IE盒子的width和height范围包含了border、padding和content
2.可以通过修改元素的box-sizing属性来改变元素的盒模型:
1)box-sizing: content-box表示标准盒模型(默认值)
2)box-sizing: border-box表示IE盒模型(怪异盒子模型)
3.弹性布局
当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式
注意,设为flex布局后,子元素的float、clear和vertical-align属性将失效。
1)6个属性设置在容器上:
flex-direction:主轴的方向
flex-wrap:换行。
flex-flow:flex-direction和flex-wrap的简写,默认值为row nowrap。
justify-content:主轴的对齐方式
align-items:交叉轴的对齐方式
align-content:多根轴线的对齐方式
2)3个属性设置在子元素上:
flex属性是flex-grow,flex-shrink和flex-basis的简写,默认值为0 1 auto。
1.flex-grow:放大比例,默认为0
2.flex-shrink:缩小比例,默认为1
3.flex-basis:最小宽度
4.js基本数据类型
基本数据类型(6种)
number
string
boolean
null
undefined
Symbol(es6):创建一个独一无二的标识
bigInt(谷歌67版本)
5.怎么判断数据类型
1)在不知道数据类型的情况下:typeof
typeof能够返回的类型有: number、string、boolean、undefined、object、function
typeof不能返回null类型,null类型进行typeof操作符后,结果是object,原因在于,null类型被当做一个空对象引用
Array和null返回的都是object
2)已知对象类型的情况下:instanceof
返回一个布尔值,这个对象是否是这个特定类或者是它的子类的一个实例。
instanceof只能正确判断引用数据类型,而不能判断基本数据类型
3)Object.prototype.toString.call() ;
使用 Object 对象的原型方法 toString 来判断数据类型:
同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?
这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。
4)constructor
('str').constructor === String
返回一个布尔值
6.基本数据类型和引用数据类型存储方式的区别
1)声明变量时的内存分配
1.基本数据类型的值存储在栈中
2.引用数据类型在栈内存中保存的是对象在堆内存中的引用地址
2)不同的访问机制
1.基本数据类型的值可以直接访问到
2.引用数据类型:首先在栈中得到这个对象在堆内存中的地址,然后按照地址获取对象中的值
3)复制变量时的不同
1.基本数据类型:将原始值的副本赋值给新变量,它们有相同的值,但是它们是完全独立的
2.引用数据类型:把内存地址赋值给新变量,这两个变量都指向了堆内存中的同一个对象,相互影响
4)参数传递的不同
1.基本数据类型:把变量的值传递给参数,参数和变量互不影响
2.引用数据类型:把内存地址传递给参数
7.引用数据类型为什么存储在堆中
堆没有结构,数据任意存放
8.箭头函数与普通函数的区别
1)箭头函数不能作为构造函数(不能new),而普通函数可以
2)箭头函数没有原型(prototype),而普通函数有
3)箭头函数不绑定arguments,而普通函数argument绑定了参数列表对象
4)this指向问题:1.箭头函数中的this指向包含该箭头函数的外部函数的this。
普通函数的this指向该函数的调用者
2.call, apply, bind会改变普通函数的this,但不会改变箭头函数的this
5)箭头函数不能用作generator函数,而普通函数可以
9.promise.resolve.then{console.log(1)}
setTimeout(console.log(2),0)
2 1
异步任务执行的优先级有区别:宏任务的优先级高于微任务
大致分为微任务(如:Promise)和宏任务(如:setTimeout)
promise.then是一个微任务
10.数组去重
1)es6的Set方法:let newArr=[...new Set(arr)]
2)利用数组的indexOf下标属性:
let arr=[1,3,5,2,4,3,6]
let newArr=[]
for(let i = 0; i<arr.length; i++){
if(newArr.indexOf(arr[i])==-1){
newArr.push(arr[i])
}
}
console.log(newArr)
3)利用数组原型上的includes方法
if(!newArr.includes(arr[i])){
newArr.push(arr[i])
}
4)将数组的每一个元素依次与其他元素做比较,发现重复元素,利用数组的splice()方法删除重复元素。
let arr=[1,3,5,2,4,3,6]
for(var i=0;i<arr.length-1;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){
arr.splice(j,1);
j--;
}
}
}
console.log(arr)
5)先将原数组排序,再与相邻的进行比较,如果不同则存入新数组。
6)利用数组原型对象上的 filter 和 includes方法。
7)利用数组原型对象上的 forEach 和 includes方法。
8)利用数组原型对象上的 lastIndexOf 方法。
11.set怎么保证没有重复的元素
12.vue组件通信的方式
1)父子组件之间的通信
1.props / $emit
1)父组件通过props向子组件传递数据:子组件的数据会随着父组件不断更新。
2)子组件通过$emit和父组件通信:$emit绑定一个自定义事件,当这个事件被执行时就会将参数传递给父组件,而父组件通过v-on监听并接收参数。
2.ref / $refs
1)在子组件上,ref的引用指向了子组件的实例。可以通过实例来访问组件的数据和方法。
2)父组件中通过this.$refs来访问
2)兄弟组件之间的通信
1.EventBus
使用场景:兄弟组件传值
创建一个中央事件总线EventBus
兄弟组件通过$emit触发自定义事件,$emit第二个参数为传递的数值
另一个兄弟组件通过$on监听自定义事件
2.$parent 或$ root
通过共同祖辈$parent或者$root搭建通信桥连
兄弟组件:this.$parent.on('add',this.add)
另一个兄弟组件:this.$parent.emit('add')
3)祖孙与后代组件之间的通信
1.$attrs 与$ listeners
使用场景:祖先传递数据给子孙
设置批量向下传属性$attrs和 $listeners
包含了父级作用域中不作为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。
可以通过 v-bind="$attrs" 传⼊内部组件
2.provide 与 inject
祖先组件通过provide发送传递的值
后代组件通过inject接收值
4)复杂关系的组件间通信
Vuex作用相当于一个用来存储共享变量的容器
13.vue生命周期
beforeDestroy
14.v-model
利用vue提供的API封装一个v-model
:bind一个input方法
15.watch和computed的区别
1)computed 计算属性 : 1.依赖其它属性值,
2.有缓存,只有它依赖的属性值发生改变时,获取 computed 的值时才会重新计算。
2)watch 侦听器 : 1.观察的作用,
2.无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
16.mixin混入
mixin(混入),提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。
本质其实就是一个js对象,它可以包含我们组件中任意功能选项,如data、components、methods、created、computed等等
我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来
混入mixin:
一个混入对象可以包含任意组件选项。当组件使用混入对象时,
所有混入对象的选项将被“混合”进入该组件本身的选项
1.data:同名,组件内部的data优先
2.值为对象的选项:methods,directives,filters,components,保留组件内部的
3.生命周期钩子函数:同时保留,但是会先执行mixin中的钩子
17.什么时候使用vuex
维护项目中的共享数据
比如当前登录者的信息,全局loading,以及一些其他共享数据
1)核心概念
state 状态,声明并且初始化共享数据
getters 获取器,对state中的数据进行过滤输出
mutations 突变,是修改state值的唯一方式,只能同步修改
actions 动作,可以通过异步操作,异步操作获取的结果如果要修改state,可以通过actions
modules 模块化
18.vue3和vue2的区别
组合式API解决的问题?
1.setup
使用 setup 函数时,它将接收两个参数:1)props; 2)context
1)props
setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。
2)context
19.状态码304
当浏览器请求未改变,并且已经有缓存的资源时,服务器会返回304,告知浏览器,
该资源从某个时间之后没有再改变,可以用在浏览器端缓存的资源
六.浩鲸科技
1.云服务器ECS容器部署,部署项目,工具,技术栈
1)容器部署:docker
2)部署项目:1.购买域名和远程服务器
2.域名解析,实名制认证,备案
3.把项目代码放在远程服务器上
4.服务器安装数据库
5.前端编译静态文件
6.nginx前端配置
7.解决前后端跨域问题
8.项目在线上跑通以及后续完善
3)工具:
4)技术栈:
2.项目中有遇到跨域问题吗?怎么解决的?
前后端分离遇到的跨域问题?前端文件和jar包在一个容器,不会产生跨域
nginx代理跨域会配置吗?
3.项目中的增删改查?
4.附件过大的话分片上传?
oss 对象存储模型,相当与文件服务器
可以解决速度慢的问题,上传超时怎么办?
5.对复杂类型数据深拷贝?
用原生js深拷贝
6.针对数组的深拷贝
7.深拷贝与浅拷贝
8.食堂可视化做了什么?功能的实现?
dashboard有很多窗口,自定义设置容器宽高度,自适应内容填充
容器布局
9.项目中的问题,难点?
类的派生:
挂同一个类下面的图片,样式相同有影响
10.H5有哪些特性?移除了哪些特性?
canvs,video,audio,本地缓存localStorage
11.display:none和visibility:hidden的区别?项目中有用到过吗
12.一个元素的水平垂直居中?
13.行内元素(文本)怎么水平垂直居中?
看w3c标准
14.选择器的优先级?
15.bootstrap使用过吗?
16.栅格系统?
栅格系统会自动把容器分为12份,我们可以自由按份组合
栅格系统通过一系列的行与列的组合来创建页面布局,我们把内容放在创建好的布局中
1)响应式的,移动设备优先
2)随着设备或视口大小的增加最多分为12份
3)包含了预定义类
17.伪类和伪元素的区别?
18.清除浮动?
父子级:
兄弟级:
19.CSS写一个轮播图?
animate
遇到了什么问题?
无限轮播
animate控制什么来动的?kfram规则控制轮播的滚动。
20.垃圾回收机制?垃圾回收流程是什么?
js具有自动垃圾回收机制,执行环境会管理代码执行的时候使用的内存
原理:垃圾收集器会定期找出那些不在继续使用的变量,然后释放其内存
两种实现方式:
1.标记清除:当变量进入执行环境时,标记这个变量为"进入环境"。进入环境的变量所占用的内存就不能释放,
当变量离开环境时,则将其标记为"离开环境",等待垃圾回收。
2.引用计数:如果一个值的引用次数是0,就表示这个值不再用到了,可以将这块内存释放。
如果一个值不再需要了,引用次数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏。
21.闭包的应用场景?
定时轮询
回退,定时器会一直挂在window上面,不会释放就导致内存不断增大
解决:销毁实例时,做一个监听器,把定时器和一些方法销毁
22.防抖与节流?
提交表单点击十几次按钮,怎么实现防抖?
做一个定时器加状态,定时一秒,一秒钟之内重新点击了按钮就不会进入提交方法。
状态没有改变的话,点击之后标记这个状态进入提交方法。
23.js对象继承的方式?原型链继承?原型链继承有什么缺点?
24.数组的遍历方法
25.es6中Map和对象的区别?
1)访问:1.map.get(key)
2.obj.a或者obj['a']
2)赋值:1.map.set(key,value),key可以是任何类型
2.object.a=1或者object['a']=1,key只能是字符串,数字或symbol
3)删除:1.map.delete,删除一个不存在的属性返回false
2.object.delete,删除一个不存在的属性返回true
4)大小:1.map.size
2.object.keys转换为数组,再通过数组的length获取长度
5)迭代:1.map有迭代器,for-of,forEach方法
2.object没有迭代器
26.空指针和undefined的区别
27.get和post的区别
28.http和https的区别?http校验的流程?
29.TCP协议?
30.使用过cookie吗?cookie和localStorage的区别?
31.token怎么校验?登录之后请求用户信息,token带在请求头?
32.设计localStorage需要有时效性,跟cookie一样有过期的功能,怎么实现?
挂一个时间戳,存储键值对时带一个时间戳(过期的标识),
setItem,getItem封装一个方法拿本地缓存的时间戳和跟当前时间对比。当前时间大于本地缓存的时间戳就自动删除,做一个过期的处理。
33.性能的优化?
1)防抖和节流
2)懒加载:实现的原理是什么?
监听滚动,根据滚动的界面看界面容器有哪些,遍历图片,用另一种方式展现出来。
3)CDN
4)回流与重绘
34.在地址栏输入url到页面的渲染发生了什么
1)URL 解析:首先判断你输入的是一个合法的URL 还是一个待搜索的关键词,并且根据你输入的内容进行对应操作
2)DNS 查询:获取到域名对应的IP地址
3)TCP 连接:三次握手建立TCP连接
4)HTTP 请求:浏览器发送 http 请求到目标服务器。(请求行,请求头,请求主体)
5)响应请求:当服务器接收到浏览器的请求之后,返回一个HTTP响应消息。(状态行,响应头,响应正文)
服务器响应后,TCP连接经过四次挥手完成断开
6)页面渲染:当浏览器接收到服务器响应的资源后,对资源进行解析