HTML
一、BFC 块级格式化上下文:里面的元素不会影响外面的元素。
- 一个BFC区域只包含其子元素,不包括子元素的子元素
- BFC区域需要一定的条件:该元素设置浮动、定位、弹性布局等
- 不同的BFC区域之间是相互独立的
二、移动端点击300ms延迟
- fastclick插件:是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。ios会首次触发不生效、需要二次触发
- touchStart配合touchend,记录的值进行对比判断
三、meta viewport 为了防止用户缩放前端页面-适配移动端页面、 meta元数据
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />
四、@import 和link引入 css
- @import先加载HTML、后加载CSS
- link先加载CSS、后加载HTML rel="stylesheet" 连接的类型 样式表
五、src和href的区别
- href指定网络资源的位置,建立和当前元素之间的连接
- src仅仅嵌入当前资源到当前文档元素定义的位置
六、伪类和伪元素的区别
- 是否创建新元素;伪类 添加特殊效果,单冒号;伪元素 双冒号
- 伪类选择器: a:link\a:visited\a:hover\a:active等
七、圣杯和双飞翼布局:三栏布局;左右固定宽度,中间宽度自适应
- 利用margin的负值、配合float进行布局;(中间盒子的左右margin或者父盒子左右padding)
- flex:父盒子设置flex,两侧设置 flex:0;flex-basic: 固定宽度。
八、渐进增强、优雅降级
- 渐进增强:针对低版本浏览器进行构建页面,保证最基本的 功能。
- 优雅降级:一开始就开始构建完整的功能,然后针对低版本浏览器进行兼容。
七、常见浏览器兼容性:
- 浏览器种类多,内核种类多,对于CSS3的部分属性不能完全兼容。 条件注释、选择器前缀法
八、重排(回流)、重绘
- 重排:当元素的位置和尺寸大小,浏览器需要重新计算元素的几何属性,像添加和删除DOM、元素尺寸改变。
- 重绘:一个元素的外观发生变化,但是没有改变布局,重新把元素外观绘制出来的过程。
- transform:不重排、不重绘。合成属性,会创建一个合成层,在合成层上渲染。
九、检测是否为数组; 原型链
- Object.prototype.toString.call() [object Array]
- Array.isArray() 、instanceof:判断该对象是谁的实例 、 typeof
十、typeof和instanceof
- typeof是一个操作符,用来检测给定变量的数据类型;原理数据底层机制,二进制判断
- instanceof是通过JavaScript原型继承机制
十一、闭包 -
- 有权访问另一个函数作用域中变量的函数
- 应用场景:函数防抖(在事件被触发N秒后再执行回调,如果在这时间内又被触发,则重新计时)
function debounce(fn, delay) {
let timer = null
return function () {
if (timer) {
clearTimeOut(timer)
timer = setTimeOut(fn, delay)
} else {
timer = setTimeOut(fn, delay)
}
}
} // 短时间内大量触发同一事件,只会执行一次函数 且肯定会执行
function throttle(fn, delay) {
let flag = true
return function() {
if (!flag) {
flag = false
}
flag = false
setTimeOut(() => {
fn()
flag = true
}, delay)
}
} // 短时间内大量触发同一事件,只会执行一次,规定时间内再次触发会阻止执行(技能冷却)
- 其他应用场景: input搜索事件,页面resize事件。
十二、原型和原型链
- 构造函数
- 每个对象都有一个
__proto__
属性,并且指向它的prototype原型对象 - 每个构造函数都有一个prototype原型对象,prototype原型对象里的constructor指向构造函数本身
- prototype对象相当于特定类型所有实例对象都可以访问的公共容器
十三、EventLoop
- JS是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列。
十四、new操作符的作用
- 内存中创造一个空对象
- this指向这个内存中的空对象
- 根据定义的键值和传入的参数,依次给这个空对象添加上键值对
- 返回这个新的对象
十五、Promise
// 手写Promise
十六、computed和watch
- computed:简化模块代码,所依赖的属性未变化时,直接去缓存,缓存是基于它们 的响应式依赖进行缓存的。
- watch:需要数据变化时执行异步或开销较大的操作时。
- 使用场景:computed:当一个属性受多个属性影响的时候。watch:当一条数据影响多个数据的时候
十七、v-for中的key的作用
- 为了更高效的对比虚拟DOM中每个节点是否是同一个节点,唯一标识。
- Vue判断两个节点是否为相同时,主要是根据两者的Key和元素类型等,若无key则会认为是两个相同的节点,会造成大量的dom更新操作。
18、父子组件通信
- props、自定义事件$emit、Ref、provide和inject等
19、双向数据绑定
- vue实例创建时,会对data中的属性进行遍历,通过Object.defineProtety转换为getter和setter且在内部追中相关依赖,在属性被访问和修改的时通知变化。
20、nextTick:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后使用$nextTick,则可以在回调中获取更新后的DOM。
21、keep-alive的实现:实现组件的缓存
Vue.js内部将DOM节点抽象成一个个的VNode节点,keep-alive组件的缓存也是基于虚拟节点的而不是直接存储DOM结构。它将满足条件的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象取出并渲染。(include、exclude配置属性)
router中 添加 meta: keepAlive标识
<keep-alive> <router-view v-if="$route.meta.keepAlive"> <!-- 这里是会被缓存的视图组件 --> </router-view> </keep-alive>
22、vuex、vue-router实现原理
- vuex:状态管理库
- state单一状态树,getter、mutation显示提交更改state
- Action提交mutation,可以包含任意异步操作
- module(当应用变的庞大复杂,拆分store为具体的module模块)
23、vue中的diff算法和patch方法
- patch:补丁,Vue更新时的patch算法,就是通过打补丁的形式充分利用原有的dom进行增加,删除和移动操作,从而避免重新创建大量的dom操作,进一步提升性能。
- diff算法过程就是调用patch函数;只能是同级比较。
- 虚拟dom:是将真实dom的数据抽取出来,以对象的形式模拟树形结构。
- diff算法触发过程: Vue的双向绑定,是通过重置Object.defineProperty中的get和set方法进行数据劫持,进而触发修改视图操作。所以当数据发生改变时,set方法会调用Dep.notify通知订阅者watcher,订阅者就会调用patch方法给真实的dom打补丁,更新响应的视图。
24、Vue的性能优化
- 第三方模块按需引入、防抖、节流、v-if替代v-show、图片路由懒加载、异步组件
25、浏览器从输入url到渲染页面
- 网络:构建请求、查找强缓存、DNS域名解析、建立TCP连接(三次握手)、发送HTTP请求
- 浏览器解析:解析html构建DOM树、解析CSS构建CSS树、样式计算、生成布局树
- 浏览器渲染:建立图层树、显示器显示内容、断开连接(四次挥手)
26、http和https区别
- 默认端口、安全性(明文传输、加密传输协议)
- http的连接无状态的,https协议是ssl+http协议构建的可进行加密传输、身份认证网络协议。
27、get和post区别
- post更安全、数据更大、发送数据类型较多、速度较慢、用于修改和写入数据
- get 回退时是无害的,而post会再次提交请求
28、三次握手、四次挥手
- 多一次握手的必要性:防止已失效的请求报文突然又传到了服务端而产生连接的误判。
- 四次挥手:即中止TCP连接,需要客户端和服务端总共发送四个包确认连接的断开。
- 多一次挥手:a:在请求连接时,服务端在收到建立连接请求的syn报文后,把ack和syn放在一个报文里发送给客户端。 b:关闭连接,当收到对方的fin报文时,仅代表对方不再发送数据但还能接收数据,我们也未必把全部数据都发给了对方,所以我们可以立即close,也可以发送一些数据给对方,再发送fin报文给对方表示同意关闭连接。因此我们的ack和fin一般会分开发送。
- ACK: 确认序号有效;SYN:建立一个新的连接;FIN:释放一个链接
29、http如何实现缓存:强缓存、协商缓存
- 强缓存:Expirse(过期时间)、Cache-Control(no-cache)协商缓存
- 浏览器会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源,否则,根据头信息向服务器发送请求,使用协商缓存,如果命中,则服务去器不返回资源,浏览器直接使用本地资源的副本,若不命中,则浏览器返回最新的资源给浏览器。
30、输入url后http请求的完整过程
- 建立TCP连接 - 发送请求行 - 发送请求头 - 到达服务器(发送状态行) - 发送响应头 - 发送响应数据 - 断TCP连接
31、跨域方式
- jsonp:利用script标签没有跨域限制,缺点:只支持get请求
- CORS(设置Access-Control-Allow-Origin: 指定可访问资源的域名)
32、浏览器的本地存储:cookie、sessionStorage、localStorage
- 都是保存在浏览器、且同源
- 不同点:
- 存储大小限制、作用域不同
- cookie:在浏览器和服务器间来回传递(4K);其他仅在本地(5M);
33、常见的webpack loader
- File-loader、image-loader、url-loader、css-loader、sass-loader、style-loader
34、javascript的继承方式
-
原型链继承:子类型的原型为父类型的一个实例对象
// 父 function Father(name) { this.name = name || 10 } Father.prototype.sayHi = function() { conosle.log('sayHi') } // 子 function Son() {} Son.prototype = new Father() Son.prototype.sayHello = function() { console.log('sayHello') } let son = new Son() son.sayHi() // 'sayHi' son.sayHello() // 'sayHello' son.name // 10 Object.getPrototypeOf(son) === son.__proto__ === Son.prototype
-
ES6中的Class继承
// 父类 class Father { constructor(age) { this.age = age } sayHi() { console.log('sayHi')} } // 子类 class Son extends Father{ constructor(name, age) { super(age) this.name = name } sayHello() { console.log('sayHello')} } let son = new Son('xsk', 18) son.name // 'xsk' son.age // 18 son.sayHi() // 'sayHi' son.sayHello() // 'sayHello'
35、call、apply和bind的区别
- call和apply改变this指向;call的性能好一点;省去了第二个参数解构赋值
- bind原理:返回一个函数,另外两个立即执行
36、浅拷贝、深拷贝
- JSON的弊端:序列化的结果会把函数或者undefined丢失; NaN、Infinity和-Infinity序列化后的值会变为null; 值有时间对象会转为字符串形式;有RegExp、Error对象,结果为空对象。
- 弊端2:构造函数实例的对象,拷贝后会丢弃对象constructor;对象中存在循环引用的情况也无法实现正确的深拷贝。