图文并茂的前端面试分享(附视频)

2,575 阅读27分钟

面试造火箭,工作拧螺丝!

============

在技术圈毕竟只有百分之一的人能进入 BAT,百分之九九的小伙伴只能在普通公司做这普通的事情,此文没有 BAT 啥经验,都是基础。帮助小伙伴们快速梳理知识,不会涉及到具体的很细节的知识点,关注面试本身。公司一般会从以下 5 个方面(HTML5+CSS3/JS / 框架 / 项目 / 工具)考察一个人的能力,此文总结了最近 2-3 年(成渝地区)常问的面试题,适合初中级(就是只要 10K 左右的小伙伴啦)前端工程师。

1、HTML(5) 和 CSS3 方面


1. 前端与后端数据交互的格式有哪些,为什么大部分现在都用 json 而不用 xml。

答:
XML:<person><name> 知了哥 </name><age>3岁</age></person>。  
JSON:{name:"知了哥",age:3} JSON 书写方便节省字节,更轻量,前后台都有直接解析 
JSON 的方法(JSON.stringfity/parse)使用方便。

2. Flex 布局熟悉吗,说几个常用的属性。

答:这个几乎每天都在用,还是挺熟悉的。  
display:flex  
align-items 多个  
align-content:单个  
justify-content  
justify-items  
flex-direction  
flex-wrap:  
flex-basic:初始盒子宽度 flex  
flex-grow:增长因子 200 4_40=160 1,1,1,2 1/5_40 flex  
flex-shrink : 缩减因子 200 60*4=240

3. 说一下 CSS 盒模型

答:CSS 的盒模型包含了一下几个内容 margin,padding,border,content。
   在计算盒子宽高的时候,IE 和 Chrome 会有一些区别,IE 算到 border,Chrome 的宽度只包含 content 区域,  
   因此 CSS3 提供了 box-sizing 这个属性来修改。

4. CSS 常用选择器,选择器权重问题。

答:*(has,not,target,root。。。。) 通配符, ID,class,attr 属性,element,子代( > + ~ ), UI 状态伪类选择器(hover,active,link,seceted..,checked), 结构性伪类选择器 (nth-child,fist-child,last,nth-of-type...before,after....)

!important > style > id > class > elemnet > 伪类和属性

5. 请用 5 种方式实现元素垂直居中。

答:1、flex

2、Tranform

3、定位 + margin 负值(知道子节点宽高)

4、定位 + margin:auto

5、JS 动态计算 top、left 值

6. 什么是 BFC?垂直 margin 重叠是为什么?怎么解决这个问题?

答:概念:BFC 全称 Block Formatting Context ,中文意思为块级格式上下文。 通俗的来说:BFC 是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子内部的元素无论如何翻江倒海,都不会影响到外部。转换为 BFC 的理解则是:BFC 中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。比如清除浮动)并且在一个 BFC 中,块元素与行元素都会垂直的沿着其父元素的边框排列。

如何触发 BFC

    1. 浮动元素,float 除 none 以外的值
  • 2.position 的值不为 static 或者 relative

  • 3.display 不为 none

  • 4.overflow 除了 visible 以外的值

BFC 的应用

  1. 解决浮动塌陷问题 2. 自适应两栏布局(我们还可以运用 BFC 可以阻止元素被浮动元素覆盖的特性来实现自适应两栏布局。方法:给没有浮动的元素加 overflow:hidden。) 3. 解决设置 margin 值重叠问题。

总结:BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。它规定了元素与其他元素的关系和相互作用。

7. 什么是浮动,有什么作用,有何副作用,以及如何清除浮动?

答:浮动是使用给节点添加 float 属性,最初的设计是用来实现文字环绕的。 添加了 float 的节点脱离文档流,同时触发节点的 BFC,让节点往一个方向靠,并排成一行。 当一个父节点的子节点全部浮动,就会造成父节点高度塌陷, 解决的办法首先是可以给父节点主动添加高度值,再者利用只要有一个子节点不浮动原理来添加一个不浮动的节点(通常使用伪元素 before,after),再者还可以触发父节点的 bfc,常用的定位,或者 overflow:hidden。

8. CSS 里面有哪些相对单位?都是相对什么的?

答:REM,EM,VW,VH 等 REM:相对于根节点 html 的 font-size EM:父节点的 font-size VW:视口的宽度为 100VW,相对于把视口分为 100 份。 VH:视口高度为 100VH,同理

以上单位都可以在移动端做页面适配,但通常使用REM和VW

9. fixed 是相对于谁定位的?如果加上 transform 会出现问题吗?

答:fixed 定位相对于浏览器视口来定位的 添加上 transform 以后,fixed 定位会失效(现在这个 bug 已经不存在啦! )。如果 fixed 元素的祖先有 transform 属性, 则 fixed 元素会相对与这个祖先计算, 而不是视口(问题还在)。

10. 为什么不推荐用 style 内联元素?内联元素有什么缺点?(css 文件可以缓存)

答:首先是 style 是节点的属性,不能被缓存;代码的可读性和可维护性相对弱一些,特别是多人协作开发的时候。但是如果一个页面的 style 样式足够少的时候,可以使用 style 元素,因为一次请求最多携带 14K 的数据,如果足够小,还可以节约一次请求。

11. 简单描述 http 或 https 协议,以及为什么要三次握手?什么是长链接

答:http(https)是超文本传输协议,基于 TCP 请求与相应的模式,无状态的,是目前主流的 web 传输协议。一般包含请求头,请求体,响应头等 目前 http 协议已经发展到 2.0 阶段,支持长链接 Connection: keep-alive,断点续传,cache 缓存策略,多路复用,服务器推送等。 https 相对于 http 更安全,增加了证书 SSL 加密,端口是 433。

三次握手其实就是三次网络连接,客户端携带 SYN=1,Seq = x 信息给服务端,服务端接受到后,服务端就知道了,有一个客户端要链接我,然后服务器就会开启一个 TCP socket 的端口,然后返回数据给前端也是 SYN=1,SEQ=Y,ACK = x+1,客户端接受到后,在发一个 seq,和 ACK+1. 主要是为了防止开启无用的链接,或者网络延迟丢包,服务器无法确定到底客户端有没有收到消息

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。 Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。 为何需要长链接? 长连接可以省去较多的 TCP 建立和关闭的操作,减少浪费,节约时间。

12. http 常见状态码有哪些?301 和 302 的区别是什么?304 是指什么?

答: 404:找不到资源; 500:服务器内部错误; 200:请求成功,并返回数据; 301:永久重定向; 302: 临时移动,可使用原有 URI; 304:资源未修改,可使用缓存; 400:请求语法错误(一般为参数错误); 403:没有权限访问。。。等

13. 浏览器页面渲染的流程是什么(输入 url 后页面发生什么)?

答: 首先 dns 解析 IP,建立 tcp 链接下载资源,构建 dom 树,当遇到 link 标签,会下载并执行解析 css(不会阻止 dom 树的构建)当遇到 script 标签的是,dom 树构建会暂停,下载并执行完 js 才会继续(defer(下载延迟执行),async(异步下载并执行)) 然后再布局和绘制(layout,paint)最后在 render

14. 什么是 reflow 与 repain?哪些操作会触发 reflow,如何避免

答:reflow:回流,当元素的尺寸、DOM 结构发生改变时,浏览器会重新渲染页面,称为回流。 repain:重绘,当元素的样式(布局不发生,color,opacity,visibility)发生改变的时候。

以下常见操作都会触发:

  • 浏览器窗口大小改变 元素尺寸、位置、内容发生改变
  • 元素字体大小变化
  • 添加或者删除可见的 dom 元素
  • 激活 CSS 伪类(例如::hover)等

通过 class 的方式集中改样式,documentFragment 缓存节点,避免使用 table、calc,做动画的节点脱离文档流(新创建图层)。总结:减少 DOM 操作!

15. HTML5 常用的特性(API)有哪些?你用过哪些?

答:语义化标签 (header,nav 等),video、audio,获取 dom 的方式(queryselector),websocket Canvas,svg,requestAnimationFrame,Geolocation,stroage ,notification,file API,Orientation API 用于检测手机的摆放方向等

16. 请列举出几个常见的浏览器兼容性问题?

答:现在市面上 IE678 基本已经停止使用了,所以尽量不要说这方面的兼容性。 有些浏览器支持的,有些呢 不支持;或者是支持的方式不一致。

  • 1、不同浏览器的默认 margin 和 padding 不一致

  • 2、图片的默认间距不一致

  • 3、获取视口的宽高 window.innerheight/width

  • 4、CSS3 的动画,过渡,渐变,flex 也有,grid

  • 5、Canvas,SVG

  • 6、IE9 以下不能的 opacity,使用 filter: alpha(opacity = 50);

  • 7、event.offsetX/Y

  • 8、绑定事件 IE9 才支持(addEventListener)

17. 什么是浏览器缓存(知道什么是 强缓存 和 协商缓存)?

答:当浏览器访问过后的资源,会被浏览器缓存的本地,当下次在访问页面的时候,如果没有过期,直接读取缓存,加快浏览器的加载效率。

http 缓存机制:1、Expires:通过设置最大缓存时间,当时间超过了就去服务器下载, 2、http1.1,cache-control:max-age = time ,当 time 过期后,检测 etag 带上 etag 往服务器发请求,如果 etag 没变,直接告诉浏览器读本地缓存,如果没有 etag 就会 检测 Last-Modified,判断 如果 上一次更改的时候,距离本次访问时间比较久,说明文件没有发生改变,返回 304。

强缓存就是当前访问时间还在设置的最大时间范围内。 协商缓存就是时间过了,通过检查 etag 或者 last-modifed 来使用缓存的机制。

18. 说一下浏览器垃圾回收机制

答: 老:标记清除算法,GC 会检测当前对象有没有被变量所引用,如果没有就回收。 新: Scavenge ,把内存空间分为两部分,分别为 From 空间和 To 空间。当一个空间满了以后,会把空间中活动对象转移到另外一个空间,这样互换。

19. 什么是事件委托

答:事件委托本质上是利用了浏览器事件冒泡的机制。因为事件在冒泡过程中会上传到父节点,并且父节点可以通过事件对象获取到目标节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式称为事件代理。使用事件代理我们可以不必要为每一个子元素都绑定一个监听事件,这样减少了内存上的消耗,也是常见的 JS 性能优化的一个点。

20. 什么是响应式布局?如何实现

答:书写一套 CSS 样式适配 PC 和移动端,让 PC 和移动端都能正常的浏览器页面。 使用 mate 控制 viewport,再配合 media query 的 screen 来设置断点样式。 注意:做相应式 不能使用固定单位,要使用 max-width、min-width 等能自动缩放的单位。

2、JS 方面 (ES6/ES7)

=================

1. 在 JS 中什么是面向对象程序设计,面向对象设计优点?

答:在 JS 中面向对象更多说的是通过构造函数或者 class 封装一个独立的功能,以达到代码的复用。 面向对象的三个特点: 封装:通过对象把属性和方法封装起来,相似对象的话采用构造函数或者类 new 得到。 继承:通过混合继承(构造函数和原型)的方式,可以达到属性和方法的复用。 多态:通过对象属性覆盖,可以让继承的对象拥有更多行为。

面向对象的程序设计是组织代码的方式,能提升开发效率和代码的可维护性。

2. 什么是原型、原型链,有什么作用?

答: 原型:每一个对象都与另一个对象相关联,那个关联的对象就称为原型。

意义:函数 Person 有一个属性 prototype,指向一个对象,对于普通函数来说没多意义,对于构造函数就有作用了,当使用 new 操作符时,会把 Person.prototype(原型对象)赋值给实例的__proto__(原型实例)属性,再通过原型查找机制所有的 Person 产生的实例都可以访问到挂载到原型上的方法,这样就达到了函数的复用,减少内存开销。

原型查找机制,通过实例调用一个属性的时候,先在实例自身对象上查找,如果实例本身上没有,就去自动去实例的__proto__上去查找。

原型链:每一个对象,都有一个原型对象与之关联,这个原型对象它也是一个普通对象,这个普通对象也有自己的原型对象,这样层层递进,就形成了一个链条,这个链条就是原型链。通过原型链可以实现 JS 的继承,把父类的原型对象赋值给子类的原型,通过原型查找机制,这样子类实例就可以访问到父类原型上的方法了。

Person.prototype.constructor == Person

Person.prototype.__proto__.constructor  == Object 

Person.prototype.__proto__ == Object.prototype
         
Object.prototype.__proto__ == null

3. 如何实现继承(ES5/ES6)?

答:
             function Anima(name){ //父类
                 this.name = name;
            }

            Anima.prototype.sayName = function(){
                  console.log(this.name)
            }

            function Person(name,age){ //子类
                Anima.call(this,name);
                this.age = age;
            }

            Person.prototype = Object.create(Anima.prototype, {
              constructor: {
                value: Person,
                enumerable: false
              }
            })

          var p = new Persion("haha",12);

          Extends //ES6

4. 什么是作用域以及作用域链?

答:作用域是指程序源代码中定义变量的区域,限定一个变量可访问范围的,作用域的本质是对象。
JS 采用的词法作用域,在书写代码的时候(定义函数的时候),作用域就已经确定好了。
在 ES6 环境下,包含 3 个作用域,全局 globel,函数作用域,快级作用域({} ) (eval)
作用域链:当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级 (词法层面上的父级) 执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。
用途是保证对执行环境有权访问的所有变量和函数的有序访问。本质为执行上下文的 scope 属性,存储所有的变量,包括局部与全局,控制变量的使用顺序。 参考文献:https://github.com/mqyqingfeng/Blog/issues/6

var b = 10; //1:输出?2:改造代码输出10或20
(function b(){
    b = 20;
    console.log(b); 
})();


var b = 10;
(function b(b) { 在这个函数b是一个常量,在函数b内部是可以使用的,但是不能修改,如果加上use strict 严格模式就会报错。
window.b = 20;
console.log(b) //输出10
})(b)

var a = 10;
(function () {
console.log(a)
a = 5
console.log(window.a)
var a = 20;
console.log(a)
})()


5. 什么是闭包,闭包的好处和坏处分别是?

答:当函数可以记住并访问外部作用域时,就产生了闭包,那个外部作用域就称为闭包。

形成的原因:外层函数的作用域对象无法释放。 作用:为了封装对象的私有属性和私有方法,避免全局变量的污染(保护一个变量,重用一个变量)。坏处:使用不当,会造成内存泄漏。

大白话来解释:函数 A 和函数 B,当内部函数 B 引用了 A 的局部变量时,函数 A 称为闭包 原因是:JS 是词法作用域,B 的作用域链上有对 A 执行环境的引用(这个执行环境用函数来表示),A 的执行环境 AO 就不会回收。

for (var i = 0; i< 5; i++){ //改造代码,每间隔一秒 输出 0-4
 setTimeout(() => {
  console.log(i);
    }, 1000)
}

6. 什么是 this,this 的常用方式有哪些?如何改变 this 的指向?

答:简单的理解:this 指向就是当前的执行上下文对象的一个引用。 JS 在运行过程中会产生执行上下文环境(context),context 记录了包含函数在哪里被调用,作用域链,OA,this 等信息,this 是 context 的其中一个属性,会在函数的执行过程中使用,它指代的上下文对象取决于函数调用的各种条件。通常 this 在函数中使用。 设计的目的:this 提供了一种优雅的方式来隐式的传递一个对象的引用,所以在函数中使用 this 可以更加方便的复用函数。

This 的使用场景:

  • 1、全局使用 this === window 很少使用,函数体包含严格模式时为 undefined

  • 2、函数当中 在全局调用这个 fn() this === window

  • 3、在方法当中使用 this === 调用当前这个函数的所在的对象啊

  • 4、构造函数 this 执向的是 new 创建出来的实例对象啊

  • 5、DOM 事件处理函数中的 this,指向当前的 DOM 节点 6、通过 bind,call,apply 操作符来显示的设置 this 的指向 bind:绑定函数里面的 this,返回新函数, call,apply:绑定并执行这个函数,前者传参是 “,” 隔开,后者是数组

  • 7、ES6 的箭头函数 箭头函数没有自己的 this,父作用域(父函数)的 this

var x = 3;
  var foo = {
     x: 2,
     baz: {
      x: 1,
      bar: function() {
         return this.x;
        }
      }
   }

  var go = foo.baz.bar;
  go()?
foo.baz.bar()?


//综合面试题
function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a();
let obj = new Foo();
obj.a();
Foo.a();

7. 手写 bind,call,apply 函数。

答案:以上都是 挂在 Function 原型上的方法。
Function.prototype.myCall = function(context,...args){// 绑定并执行 // 执行函数
  var fn = this; 
  context.fn = fn; 
  context.fn(...args); 
  delete context.fn 
} 

Function.prototype.myBind = function(context){//绑定返回新的执行函数
     //判断调用者是不是函数
     if(typeof this != 'function'){
         throw new Error("Error")
     }
     //截取传递的参数
     let args = [...arguments].slice(1);
     var _this = this;//保存一下当前的调用者  
     return function F() {
       return _this.apply(context,args.concat([...arguments]))
     }
   } 

 function polyfillBind (fn, ctx) { //尤大
   function boundFn (a) {
    var l = arguments.length;
    return  l ? l &gt; 1? fn.apply(ctx, arguments): fn.call(ctx, a): fn.call(ctx)
 }

 boundFn._length = fn.length;
 return boundFn
}

 function polyfillBind (fn, ctx) { //尤大
   function boundFn (a) {
    var l = arguments.length;
    return  l ? l &gt; 1? fn.apply(ctx, arguments): fn.call(ctx, a): fn.call(ctx)
 }

 boundFn._length = fn.length;
 return boundFn
}

8. 什么是深、浅拷贝,请写出代码

答:浅拷贝,就是复制一个对象,当对象的属性值没有引用类型的时候。

Object.assign 迭代(for..in for..of object.enteries) 扩展运算符...,JSON.parse 等

反之如果对象中还有引用类型,连着引用类型一并拷贝称为深拷贝。 JSON 对象的方法(会忽略到值为函数和 undefined 的属性),递归


let skuObj = {...this.goodsSku,...{color,size,mate,from}} // 浅拷贝一个对象  
let skuObj = Object.assign({},this.goodsSku,{color,size,mate,from})

function deepCopy(obj){ // 判断对象的类型 
  var newObj = Array.isArray(obj)?[]:{}; if(obj && typeof obj == "object"){ // 迭代 
  for(var key in obj){ 
    if(typeof obj[key] == 'obj'){ 
       newObj[key] = deepCopy(obj[key]) 
    }else{ 
      newObj[key] = obj[key]
    }  
   } 
} 
   return newObj
} 

9. 什么是 Ajax,如何封装一个 Ajax?Get 请求与 Post 请求的区别?

答:Ajax 的全称是异步的 js 与 xml 技术,通过它与后台服务器进行数据交换,可以使网页实现异步更新,言外之意是在不重新加载整个页面的情况下,对网页进行局部更新。

 1.nex xmlhttprequset对象
 2.open(method,url,true)
 3.绑定redaystatechange事件
 4.调用send方法,如果是post请求,可以传递参数

前端的请求方式除了常用 Get 和 Post,还有 update,delete,put 等(restful api 设计) 三分方面来说:能不能缓存,传参数方式,传参大小

GET 请求可被缓存,保留在浏览器历史记录中 ,请求的参数是直接跟在 URL 上,因此不应传递敏感数据。 GET 请求有长度限制 (2048 字符),IE 和 Safari 浏览器限制 2k;Opera 限制 4k;Firefox,Chrome 限制 8k 。 GET 请求通常只应当用于从后台获取数据。

POST 请求不会被缓存,不会保留在浏览器历史记录中 POST 请求对数据长度没有要求。 POST 请求通常用于往后台提交数据。

10. 说一些 ES6、ES7 新特性。

答: let /const 定义变量(块级作用域);解构,从对象和数组中提取值;箭头函数;字符串模版;扩展运算符...;对象的简写;module;promise(async);class;对原生对象的扩展(新增加了很多方法) ;for-of (Object.keys,values,entries 等);Symbal(); 不常用的 proxy,reflect,generate 函数,map 和 set

11. 什么是 Promise,如何使用?

答:Promise 对象是 ES6 异步编程一种解决方案,通常用来解决异步嵌套和多异步同时完成回调等问题。我的理解就是:在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了。 Promise 是一个构造函数,相当于一个容器,把异步代码包裹在里面,promise 有三个状态(pending(进行中)、fulfilled(已成功)和 rejected(已失败))初始化为 pending,当异步请求成功后调用 resolve 函数,状态从 pending--->fulfilled,失败的时候调用 reject,状态从 pending--->rejected。状态不可逆。 缺点:书写麻烦,不能实现异步代码,同步执行的需求(配合 async 函数使用即可)

12. 什么是跨域,解决跨域常用的方式有哪些?

答:跨域是浏览器端行为,根据同源策略,当请求的协议、域名、端口只有一个不同,就会跨域,跨域是浏览器为了安全存在的机制,浏览器会把跨域请求的数据去掉,同时报错。 在实际开发难免会出现跨域的情况,解决方案通常有

  • JSONP 技术,利用了 script 的 src 属性没有跨域限制,img 的 src 也没有跨域限制
  • CORS,当在相应头信息中添加 access-control-allow-origain 属性,浏览器读取到就会允许返回数据。后台配置,或者下一个浏览器插件即可。
  • 后台代理(Node)
  • Iframe 域的提升(很少)

13. 什么是函数的防抖、节流,并手写基本代码

答:防抖和节流都是为了提升运行效率,减少函数的执行次数。 防抖: 把多次函数执行,合并成一次执行。给定一个间隔时间,当两次函数执行的间隔时间大于了给定的间隔时间,就执行一次函数。

       function debounce(fn,delay){ //fn真正执行的函数,delay间隔时间
                var timer = null;
                 return function(){
                    var args = arguments;
                    var that = this;
                    if(timer) clearTimeout(timer)
                    timer = setTimeout(function(){
                        fn.apply(that,[...arguments])
                    },delay)
                 }
    
       }

节流 :减少函数执行的频率。规定一个单位时间,在单位时间内触发一个事件回调, 触发时超过间隔时间则执行,否则不执行。

 function throttle(fn,gapTime){
      let _lastTime = null;
      return function(){
        var that = this;
        var args = arguments;
        let _nowTime = + new Date();
        if(_nowTime-_lastTime > gapTime || !_lastTime){
           fn.apply(that,args);
           _lastTime = _nowTime;
        }
      }
 }

什么事件循环(Event Loop)?

答:js 是非阻塞单线程语言,js 在执行过程中会产生执行环境,执行环境会被顺序的加入到执行栈,当遇到异步任务,会添加到 task 队列当中,执行同步栈,当同步栈执行完以后,event loop 就会从异步 task 队列当中提取要执行的代码放到执行栈中。这个一个过程称为事件循环。所以 JS 的异步还是同步过程。

          console.log('script start')
    
          setTimeout(function() {
            console.log('setTimeout')
          }, 0)
    
          new Promise(resolve => {
            console.log('Promise')
            resolve()
          }).then(function() {
              console.log('promise1')
            }).then(function() {
              console.log('promise2')
            })
    
          console.log('script end')
          //输出结果?

前端安全你有了解吗?什么是 XSS 攻击和 CSRF 跨站请求伪造?怎么预防?

答:前端的安全问题,在工作过程中会注意这些问题。 1、XSS 跨站脚本漏洞攻击,通常不信任用户的输入,转义输入输出内容(encodeURIComponent),括号 尖括号等。利用用户对站点的信任

2、CSRF 跨站请求伪造 是一种挟制用户在当前已登录的web应用中执行非本意的攻击 大白话:利用用户登录态发起恶意请求 网站对用户的信任

添加验证码(体验稍微差一些),不让第三方访问 cookie 对 cookie 设置 samesite, 请求验证 加 token ,

3、密码问题:对密码进行加密(MD5 等)

如何处理精度丢失问题?

答:产生的原因:JS 使用 64 位表示 Number 类型一个数字。

计算机先把 10 进制转位 2 进制,0.1 和 0.2 转成二进制的时候还会无限循环,由于有 52 位位数的限制,多余的会被裁掉,所以在进制之间转换就会丢掉精度。 通常可以把小数乘以倍数转成正整数,计算完后再转回去。 parseFloat((0.1 + 0.2).toFixed(10))

前端常用请求数据的方式有哪些,并说出各自的区别。

答:前端进行网络请求常用的 form,Ajax,fetch 常用的库文件 Jquery 或者 axios 等。

Form提交数据页面会刷新,使用体验不佳。 Ajax是一个综合技术,可以实现异步更新页面内容。使用起来方便,通常使用JQ的封装,会额外的JS加载代价。 Fetch是新的API,比较底层。目前浏览器兼容性问题多一些,比如老版本不会携带cookie,不能直接传递JS对象作为参数,不支持JSONP等 "fetch" in window Websocket

如何检测一个对象一定是数组?

答:

  • 1、Object.prototype.toString.call(),前提是 toString 方式没有被重写。
  • 2、instanceof 内部机制是通过判断对象的原型链中是不是能找到类型的 prototype。 [] instanceof Object; // true Array.prototype === arr.「proto」
  • 3、Array.isArray() ES5 新增的方法,兼容性稍微差一些。

JS 加载会阻塞页面渲染吗?会的话该怎么解决呢?

答:会 defer:并行下载,在页面解析完后执行,会按照 script 的顺序执行。(常用) async:异步下载代码,下载完毕后立即执行代码,不会按照页面的 script 顺序。

常见前端性能优化有哪些?

答: 1:加载优化

 CDN,文件压缩混淆合并,按需加载(异步组件),
 前端缓存(url,dom,localstore,cookie),浏览器缓存(cache-control,exprices),
 图片懒加载DNS预先解析dns-prefetch,服务器渲染 nuxt,next(SEO)

2:脚本优化

减少合并DOM操作(createDocumentFragment),CSS3代替js动画,缓存变量, 用requestAnimationFrame代替setTimeout,减少reflow与repain,事件代理, 开启GPU渲染tranfrom:translateX(0);防抖和节流

3:图片优化

雪碧图(减少请求),使用SVG和iconfont(字体图片)代替图片,图片压缩 2:脚本优化

减少合并DOM操作(createDocumentFragment),CSS3代替js动画,缓存变量, 用requestAnimationFrame代替setTimeout,减少reflow与repain,事件代理, 开启GPU渲染tranfrom:translateX(0);防抖和节流

3:图片优化

雪碧图(减少请求),使用SVG和iconfont(字体图片)代替图片,图片压缩

正则表达式

答:正则表达式在面试中出现的概率很高

参考文献: http://jquery.cuishifeng.cn/regexp.html

String.prototype.trim = function(){
   return this.replace(/(^\s*)|(\s*$)/g,'')
}


 reg = /[^\s]+/g; //匹配非空格正则
 let resultarr = [];      
 str.split(/\n/).forEach((item,index)=>{
     return resultarr.push(item.match(reg));
 })

var money = 141412301.11
function current(money){
   var mon = money+'';
   let [yuan] = mon.split('.')
   if (yuan.length<=3) {return mon}
   var reg = /(\d)(?=(\d{3})+(?!\d))/g; //找到某一个字符,这个字符后面要有多个3个连续的数字
   //并且不以数字结尾
   return mon.replace(reg,'$1,')
}

常用的前端缓存数据(不是浏览器缓存)方式有哪些?说出他们的优缺点。

答: URL:存储有限,数据直接放到 url 上面,不能放敏感信息 Cookie:存储有限,每次请求都会带上 cookie,会造成请求资源浪费 DOM 节点:H5 标准通过 data-xx 为节点添加自定义属性,存储有限,DOM 操作的时候非常方便。 本地存储(storage):存储 5M 左右,可以永久存储和会话存储,api 方便,只能存字符串。 indexDB:前端数据库,键值对的方式存储,可以做离线应用,学习成本高,使用场景少。

谈谈你对前端模块化理解?简单描述一下 AMD,CMD,ES6(module)之间的区别

答: 前端的模块化是把一个 js 文件看成一个模块,然后对外暴露方法和属性。 在早些年浏览器不支持模块化,社区有 AMD,CMD 两个标准,把代码封装在一个函数内部,通过请求的方式去动态的加载 js 文件。 AMD 与 CMD 两者的区别为,前者为异步预先加载代码并执行;后者为异步加载,当使用到模块提供的函数的时候,在执行(延迟执行)。 ES6 以后开始 JS 开始支持模块化,之前的模块化使用就很少了。

== 判断的转化规则?

答: 当左右两边数据类型不相同的情况下,对象和字符串比较,是对象转字符串;undefined==null;其他情况都是把值转成数字,而对象转成数字要先经过 toString 转成字符串,再转成数字。

if(a==1 && a==2 && a==3){
   console.log(ok)
}

// 思路一,为把 a 定义为对象 {},当对象与数字比较的时候,会先调用 toString 方法,我们给当前的对象添加一个私有的 tostring 方法即可,就不会去调用原型上的方法了。
// 思路二,使用属性劫持 Let n = 0 Object.defineProperty(window,a,{get(){ return ++n } }) var a = { n:0, toString(){ return ++this.n } }

通过 new 操作符调用构造函数,会经历哪些阶段?

答:1、创建一个新的对象; 2、链接到原型; 3、将构造函数的 this 指向这个新对象,执行构造函数的代码,为这个对象添加属性,方法等; 4、返回新对象。

请写出以下代码的输出,并解释

数组和字符串有哪些原生方法?(包括常用的 ES6/7)

答:详见文档 (这些常用方法都记不住!要什么自行车)

什么是 polyfill?

答:Polyfill 指的是用于实现浏览器并不支持的原生 API 的代码。 比如说 Object.assign() 是很多现代浏览器都支持的原生 Web API,但是有些古老的浏览器并不支持,那么假设有人写了一段代码来实现这个功能使这些浏览器也支持了这个功能,那么这就可以成为一个 Polyfill。

我是彩蛋:如果伙计们觉得看文字比较蛋疼,还有录制好的视频哦 -- 蛋糕老师(留言私信发地址!!!)

本文使用 mdnice 排版