前端面试题整理(部分)

HTML
一、BFC 块级格式化上下文:里面的元素不会影响外面的元素。
  • 一个BFC区域只包含其子元素,不包括子元素的子元素
  • BFC区域需要一定的条件:该元素设置浮动、定位、弹性布局等
  • 不同的BFC区域之间是相互独立的
二、移动端点击300ms延迟
  • fastclick插件:是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉。ios会首次触发不生效、需要二次触发
  • touchStart配合touchend,记录的值进行对比判断
三、meta viewport 为了防止用户缩放前端页面-适配移动端页面、 meta元数据

四、@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标识

  •   
           
          
          
      
    
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到渲染页面
  1. 网络:构建请求、查找强缓存、DNS域名解析、建立TCP连接(三次握手)、发送HTTP请求
  2. 浏览器解析:解析html构建DOM树、解析CSS构建CSS树、样式计算、生成布局树
  3. 浏览器渲染:建立图层树、显示器显示内容、断开连接(四次挥手)
26、http和https区别
  1. 默认端口、安全性(明文传输、加密传输协议)
  2. http的连接无状态的,https协议是ssl+http协议构建的可进行加密传输、身份认证网络协议。
27、get和post区别
  1. post更安全、数据更大、发送数据类型较多、速度较慢、用于修改和写入数据
  2. get 回退时是无害的,而post会再次提交请求
28、三次握手、四次挥手
  1. 多一次握手的必要性:防止已失效的请求报文突然又传到了服务端而产生连接的误判。
  2. 四次挥手:即中止TCP连接,需要客户端和服务端总共发送四个包确认连接的断开。
  3. 多一次挥手:a:在请求连接时,服务端在收到建立连接请求的syn报文后,把ack和syn放在一个报文里发送给客户端。 b:关闭连接,当收到对方的fin报文时,仅代表对方不再发送数据但还能接收数据,我们也未必把全部数据都发给了对方,所以我们可以立即close,也可以发送一些数据给对方,再发送fin报文给对方表示同意关闭连接。因此我们的ack和fin一般会分开发送。
  4. 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;对象中存在循环引用的情况也无法实现正确的深拷贝。

你可能感兴趣的:(前端面试题整理(部分))