2019-07-03|2019-07-03 初级前端面试题个人汇总

一、HTML 1.1 你是如何理解HTML语义化的?

  • 语义化指的就是根据内容的结构化,选择合适的标签,便于开发者阅读和维护。
  • 我平时写的代码都是语义化的代码,标题我就写h1-h6,文章我就写article,如果是时间,我就会用timer标签,如果是一个画板我就用canvas标签,这就是HTML语义化。
1.2 meta viewport 是做什么用的,怎么写? (换句话说,你如果手机页面不缩放,应该怎么写)

var canvas = document.getElementById('canvas')//获取画布句柄 var ctx = canvas.getContext('2d'); //需要指明2d上下文ctx.fillStyle = 'green' ctx.fillRect(10,10,100,100)//画一个矩形,参数依次为 x坐标,y坐标,宽度,高度

2D上下文:从坐标的左上角的,width 和 height 水平和垂直方向的可用像素
  • video ( 用于在HTML或者XHTML文档中嵌入媒体播放器,用于支持文档内的视频播放)

【2019-07-03|2019-07-03 初级前端面试题个人汇总】在HTML中写入video标签,属性有controls,autoplay,标签里面写几个source标签,这是因为不同的浏览器支持的播放格式不一定一致,然后浏览器会使用它所支持的第一个源。
1.4 H5是什么?
  • 移动端页面
1.5 canvas跟svg的区别 2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
1.5 响应式布局
  • css根据屏幕宽度,自动调整网页div显示和布局,以适应不同尺寸屏幕优化浏览体验。
二、CSS 2.1 两种盒模型
  • 分为border-box(IE盒模型)和content-box(W3C盒模型)
  • 区别:border-box的宽度width将padding和border算在里面,而content-box没有
  • 举个例子:如果我需要一个这样的布局,要一个div的整体宽度是页面的50%,并且这个div还带一个10px的边框
IE盒模型
div{ width:50%; border:10px solid black; box-sizing:border-box; /* 设置为IE盒模型标准 */ }

W3C模型
div{ width:calc(50%-20px); border:10px solid black }

css3的计算属性calc()兼容性一般
2.2 如何实行垂直居中
  • 若元素是单行文本, 则可设置 line-height 等于父元素高度
  • 在不在的自己的高度和父容器的高度时候,利用绝对定位是需要三行:
.father{ position:relative } .child{ positon:absolute; top:50%; transform:translateY(-50%) }

  • 不考虑兼容性的话,用Flex布局
.father{ display:flex; align-items:center; }

2.2 如何实行水平居中
  • 若是行内元素, 给其父元素设置 text-align:center,即可实现行内元素水平居中.
  • 若是块级元素, 该元素设置 margin:0 auto即可.
水平居中较为简单, 共提供了8种方法, 一般情况下 text-align:center,marin:0 auto; 足矣
① text-align:center;
② margin:0 auto;
③ width:fit-content;
④ flex
⑤ 盒模型
⑥ transform
⑦ ⑧ 两种不同的绝对定位方法
垂直居中, 共提供了8种方法.
① 单行文本, line-height
② 单行或多行文字, 使用 display: inline-block, vertical-align: middle; 加上伪元素辅助实现
③ 在最外層寫一個偽table,也就是display:table,然後在要垂直置中的區塊,加上display:table-cell以及vertical-align: middle
④ flex
⑤ 盒模型
⑥ transform
⑦ ⑧ 两种不同的绝对定位方法
设置父元素相对定位(position:relative), 子元素如下css样式:
.son{ position:absolute; top:50%; height:固定; margin-top:-0.5高度; }

.son{ position:absolute; height:固定; top:0; bottom:0; margin:auto 0; }

2.3 flex怎么用,常用的属性有哪些
  • Flex布局的父元素共有6种属性可以设置
flex-direction属性决定主轴的方向
flex-wrap属性决定当子元素的总和大于父元素时候是否换行
flex-flow属性是flex-direction和flex-wrap的组合,它是将这两个属性写到一起,先写flex-direction,后写flex-wrap,默认值为row nowrap
justify-content属性定义子元素在主轴上的对齐方式
align-items属性定义子元素在侧轴上的对齐方式
align-content属性定义子元素多根轴线在侧轴上的对齐方式,只在多行显示下有效。
  • Flex布局的子元素共有6种属性可以设置
flex-grow 属性表示当父元素空间有剩余时,将剩余空间分配给各子元素的比例
flex-shrink属性与flex-grow属性的作用相反,表示当子元素宽度总和大于父元素宽度,且未换行显示时,各子元素压缩大小,默认为1,表示各子元素等比压缩
flex-basis属性可以用来设置子元素的空间,默认值为auto,表示为原本大小
flex属性是flex-grow、flex-shrink和flex-basis的合集,默认值为0 1 auto,后两个属性可不写
order属性定义子元素在排列顺序,默认值为0,值越小越靠前
align-self属性允许子元素单独设置对齐方式,优先级比父元素的align-items高。默认值为auto,表示继承父元素的align-items
Flex布局
2.4 BFC是什么?
  • BFC的名称是块级格式化上下文
  • 如果我们给一个div加上overflow:hidden,那么这个div里面的浮动元素就会被他包裹起来。
  • 通俗一点来讲,触发BFC就是将触发的区域当作一个容器,,这个容器管理着里面的块级元素。BFC内部元素与与外部元素相互隔离,从而使内外元素的定位不会相互影响。
2.5 CSS选择器的优先级
  • 越具体优先级越高
.xxx :not(.xxx):first-child{}

  • 写在后面的覆盖前面的
  • important!优先级最高,少用
2.5 清除浮动
.clearfix{ content:''; display:block; clear:both; }.clearfix 加到容器元素上,里面的子元素的浮动就被清除了

2.6 rem
  • rem是相对于根元素的字体大小的单位
2.7 行内元素,块状元素,行内块元素 2.7.1 行内元素
  • 设置宽高无效
  • 对margin仅设置左右方向有效,上下无效
  • 不会自动进行换行
2.7.2 块状元素
  • 能够识别宽高
  • margin和padding的上下左右均对其有效
  • 可以自动换行
  • 多个块状元素标签写在一起,默认排列方式为从上至下
2.7.3 行内块元素
  • 不自动换行
  • 能够识别宽高
  • 默认排列方式为从左到右
2.7.4 行内块元素在同一行显示时有默认空隙,如何解决
  • 原因:换行显示或空格分隔的情况下会有间距
  • 使用margin负值
  • 父元素使用font-size:0
.space { font-size: 0; } .space a { font-size: 12px; }

  • 使用letter-spacing
  • 使用word-spacing
三、原生JS 3.1 ES6语法知道哪些,分别怎么用? 3.1.1 let const
  • let的作用域是块,而var的作用域是函数,let其作用域为该语句所在的代码块内,不存在变量提升;
  • const定义的变量不可以修改,而且必须初始化,以及不能重新声明。
const定义的变量,不能修改栈内对应的值或者地址。
  • 函数提升优先于变量提升,函数提升会把整个函数挪到作用域顶部,变量提升只会把声明挪到作用域顶部
  • var 存在提升,我们能在声明之前使用。 let 、 const 因为暂时性死区的原因,不能在声明前使用
  • var 在全局作用域下声明变量会导致变量挂载在 window 上,其他两者不会
  • let 和 const 作用基本一致,但是后者声明的变量不能再次赋值
const有let的所有特性; 然后const不一定是常量 const obj = {a:1} obj.a=2 obj.b=2 是可行的, const obj = {a:1} obj = {a:2} 不可行,

3.1.2 箭头函数
  1. 没有 this
  2. 没有 arguments
  3. 不能通过 new 关键字调用
  4. 没有原型
var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor

3.1.3 函数默认参数值
function multiply(a, b = 1) { return a * b; }

3.1.4 展开运算符
2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
3.1.5 模板字符串
let bianliang = 1111; console.log(`输出的会是 ${bianliang}`);

3.1.5 解构赋值
var a, b; [a=5, b=7] = [1]; console.log(a); // 1 console.log(b); // 7

3.1.6 Promise
  • Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值。
  • Promise 最直接的好处就是链式调用
3.2 手写函数防抖,函数节流 3.2.1 函数防抖
function fn(){} var timerId = null button.onclick = function(){ if(timerId){ window.clearTimeout(timerId) } timerId = setTimeout(()=>{ fn() timerId = null },5000) }

3.2.2 函数节流
function fn(){} let cd = false button.onclick = funciton(){ if(cd){}else{ fn() cd = true let timerId = setTimeout(()=>{ cd = false },5000) } }

3.4 手写AJAX
let request = new XMLHttpRequest() request.open('GET','/xxx') request.onreadystatechange = function(){ if(request.readyState === 4){ console.log('请求完成') if(request.response.status >= 200 && request.response.status < 300){ console.log('请求成功') }else{} }} request.send()

3.5 this (如何正确判断 this?箭头函数的 this 是什么?)
  • 对于直接调用 foo 来说,不管 foo 函数被放在了什么地方, this 一定是 window
  • 对于 obj.foo() 来说,我们只需要记住,谁调用了函数,谁就是 this ,所以在这个场景下 foo 函数中的
    this 就是 obj 对象
  • 对于 new 的方式来说, this 被永远绑定在了 c 上面,不会被任何方式改变 this
1. fn() this => window 2. obj.fn() this => obj 3. fn.call(xxx) this => xxx 4. fn.bind(xxx) this => xxx 5. fn.apply(xxx) this => xxx 6. new Fn() this => 新的对象 7. fn=()=>{} this => 外面的this

3.6 闭包及其立即执行函数 3.6.1 闭包
  • 概念:一个函数和这个函数内部能访问到的变量(也叫环境)的总和就是闭包

    2019-07-03|2019-07-03 初级前端面试题个人汇总
    文章图片
  • 作用:通常用来创建内部变量,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。
  • 缺点:内存消耗大,IE容易造成内存泄露,函数调用完手动回收变量!
3.6.2 立即执行函数
  • 概念:声明一个匿名函数,然后立马执行这个函数

    2019-07-03|2019-07-03 初级前端面试题个人汇总
    文章图片
  • 作用:创建一个独立的作用域。这个作用域里面的变量,外面访问不到(即避免「变量污染」)。
3.7 什么是JSONP,什么是CORS,什么是跨域?
3.7.1 JSONP
概念:JSONP是一种非正式传输协议,用来跨域请求的
原理:允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

  • JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击
1. 知道 jsonp 么? 答:知道,可以实现跨域请求;2. 为什么 ajax 不可以,但是 jsonp 可以实现跨域请求呢? 答:因为 jsonp 是通过插入一个 script 标签,利用 script 可以跨域请求来实现的。 答:面试官傻逼,ajax 现在也可以使用 cors 来做跨域请求;2.5 jsonp 实现原理? 答:通过创建一个 script 标签,将 src 设置为目标请求,插入到 dom 中,服务器接受该请求并返回数据,数据通常被包裹在回调钩子中;3.可以用 jsonp 发送 post 请求么? 答:显然不行,因为JSONP是通过动态创建标签来发送请求,只支持发送GET请求4. 参考 jsonp,还有那些发送跨域请求的途径? 答:img link iframe 等元素都可以发送跨域请求呀!5. img link iframe script 来发送跨域请求有什么优缺点?

3.7.2 CROS
概念:跨域资源共享,是AJAX跨域请求资源的方式
Access-Control-Allow-Origin的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
// 限制当前请求http://a.code.com:8080可以获取数据 header("Access-Control-Allow-Origin", "http://a.code.com:8080"); // 接受任何请求 // header("Access-Control-Allow-Origin", "*");

CORS和JSONP的应用场景区别?
CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。
3.7.3 跨域
  • 协议+域名+端口
3.8 async/await 怎么用,如何捕获异常?
  • await 只能放在async函数里面
  • 为什么要用 await
async/await是generator的语法糖,让异步代码写成同步的样式
  • 所有async函数都会返回一个Promise函数
  • 如果要await多个请求,需要借用Promise.all()
async function test(){ try{ let n = await Promise.all([fn1,fn2]) }catch(err){ console.log('失败的结果') } }

3.9 JS如何实现对象深拷贝
  • 递归
  • 判断类型
  • 循环引用
  • 深拷贝,就是遍历那个被拷贝的对象
  • 判断对象里每一项的数据类型
  • 如果不是对象类型,就直接赋值,如果是对象类型,就再次调用deepCopy,递归的去赋值。
function deepClone(source){ const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象 for(let keys in source){ // 遍历目标 if(source.hasOwnProperty(keys)){ // 意思就是__proto__上面的属性,我不拷贝 if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下 targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = deepClone(source[keys]); }else{ // 如果不是,就直接赋值 targetObj[keys] = source[keys]; } } } return targetObj; }

var targetObj = JSON.parse(JSON.stringify(copyObj))
如果你的对象里有函数,函数无法被拷贝下来
无法拷贝copyObj对象原型链上的属性和方法
3.10 如何用正则实现trim
function trim(string){ return string.replace(/^\s + |\s + $/g,'') }

3.11 不用class实现继续 原型,继承
3.11.1 原型模式
  • 每个函数都有一个prototype(原型)属性
  • 这个属性都有一个指针,指向一个对象(原型对象)
  • 这个对象包含由特定类型所有实例共享的属性和方法
  • 使用原型的好处是 可以让所有对象实例共享它包含的方法和属性
  • 对象的 _proto_ 属性指向原型, _proto_ 将对象和原型连接起来组成了原型链
3.11.2 原型链
在 javaScript 中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null 为止(也就是不再有原型指向),组成这条链的最后一环。这种一级一级的链结构就称为原型链
  • 不用class实现继承
function Animal(color){ this.color = color } Animal.prototype.move = function(){}function Dog(color,name){ Animal.call(this,color) //得分点 this.name = name }function temp(){} temp.prototype = Animal.prototype Dog.prototype = new temp()Dog.prototype.constructor = Dog Dog.prototype.say = ()=>{console.log('汪汪')}var dog = new Dog('黄色','阿黄')

  • 用class实现继承
class Animal{ constructor(color){ this.color = color } move(){ console.log(this) } }class Dog extends Animal{ constructor(color,name){ super(color) this.name = name } say(){ console.log('汪汪') } }let dog = new Dog('颜色','姓名')

3.12 实现数组去重
  1. hash
  2. [...new Set(array)]
  3. WeakMap (支持所有类型的去重 )
ES5 function unique(array){ let hash = {} let number = [] for(let i = 1; i

ES 6 function unique(array){ return Array.from(new Set(array)) }

3.13 手写Promise
function Promise(executor) { let self = this; self.status = 'pending'; //等待态 self.value = https://www.it610.com/article/undefined; //成功的返回值 self.reason = undefined; //失败的原因function resolve(value) { if (self.status ==='pending') { self.status = 'resolved'; self.value = https://www.it610.com/article/value; } } function reject(reason) { if (self.status ==='pending') { self.status = 'rejected'; self.reason = reason; } } try { executor(resolve, reject); } catch (e) { reject(e); // 捕获时发生异常,就直接失败 } } //onFufiled 成功的回调 //onRejected 失败的回调 Promise.prototype.then = function (onFufiled, onRejected) { let self = this; if (self.status === 'resolved') { onFufiled(self.value); } if (self.status === 'rejected') { onRejected(self.reason); } } module.exports = Promise;

测试
let Promise = require('./Promise'); let promise = new Promise(function (resolve, reject) { resolve(100); })promise.then(function (data) { console.log('data:', data); },function (err) { console.log('err:', err); })

3.14 如何判断变量的类型
2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
3.14.1 typeof vs instanceof
涉及面试题:typeof 是否能正确判断类型?instanceof 能正确判断对象的原理是什么?
  • typeof 对于原始类型来说,除了 null 都可以显示正确的类型
  • typeof 对于对象来说,除了函数都会显示 object
typeof [] // 'object' typeof {} // 'object' typeof console.log // 'function'

  • instanceof 能正确判断对象的原理:因为内部机制是通过原型链来判断
3.15 在JavaScript中,有三种常用的绑定事件的方法
  1. 在DOM元素中直接绑定;

  1. 在JavaScript代码中绑定;
例如,为 id="demo" 的按钮绑定一个事件,显示它的 type 属性:

  1. 绑定事件监听函数
button.addEventListener("click", function (evt) { ... }, true); // IE9, IE9+, Chrome, Safari, Opera button.attatchEvent("onclick", function () { ... }); // IE9-

3.16 数组里面有哪些遍历方法 3.16.1 for循环
var a = [1, 2, 3, 4, 5]; for (var i = 0; i < a.length; i++) { console.log(a[i]); }

3.16.2 forEach,some和every
  • forEach 会遍历数组中的所有值并忽略回调函数的返回值
var a = [1, 2, 3, 4, 5]; a.forEach(function (i) { console.log(i); //1 2 3 4 5 // return true ,return false 或者不写返回值,结果都一样 })

  • some(..):一直运行直到回调函数返回 true (或者“真”值).返回true时相当于在for循环里break,会提前终止循环
var a = [1, 2, 3, 4, 5]; a.some(function (i) { if (i === 3) { return true; } console.log(i); //1 2 return false; //回调函数默认返回false,这里不写也可以 });

  • every(..):一直运行直到回调函数返回 false (或者“假”值).返回false时相当于在for循环里break,会提前终止循环
var a = [1, 2, 3, 4, 5]; a.every(function (i) { if (i === 3) { return false; } console.log(i); //1 2 return true; //回调函数默认返回false,这里return true必须要写,否则在遍历第一个属性值之后就会终止循环 })

3.16.3 for..in和for..of
  • for..in循环可遍历对象的所有可枚举属性,所以一般用来遍历对象而不是数组,否则如果数组对象包含其他可枚举属性,遍历结果就会和期望结果不同
var a = [1,2,3]; a.ex = "ex"; //注意这里遍历的只是属性 for(var i in a){ console.log(i); // 0 1 2 ex }

  • for..of :为了弥补for..in循环遍历数组的缺陷,ES6推出了for..of循环
3.16.4 map() ,filter(),reduce()
3.16.5 while
3.17 JS的执行机制
  • javascript是一门单线程语言
  • Event Loop是javascript的执行机制

    2019-07-03|2019-07-03 初级前端面试题个人汇总
    文章图片
2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
3.18.1 浏览器中的 Event Loop
macro-task(宏任务): setTimeout, setInterval, setImmediate(ie浏览器特有),MessageChannel
micro-task(微任务): Promise.then,Object.observe(已废弃), MutationObserver
  • 首先执行同步代码,这属于宏任务
  • 当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
  • 执行所有微任务
  • 当执行完所有微任务后,如有必要会渲染页面
  • 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数
3.18.2 Node 中的 Event Loop
macro-task(宏任务): setTimeout, setInterval, setImmediate, I/O
micro-task(微任务): process.nextTick,Promise.then,Object.observe(已废弃), MutationObserver(vue中使用但由于不兼容放弃)
  • Node 的 Event Loop 分为 6 个阶段,它们会按照顺序反复运行。每当进入某一个阶段的时候,都会从对应的回调
    队列中取出函数去执行。当队列为空或者执行的回调函数数量到达系统设定的阈值,就会进入下一阶段。
3.19 call()、apply()、bind()
  • 不同之处在于,call 方法传递给调用函数的参数是逐个列出的,而 apply 则是要写在数组中。
  • 核心要点: 可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 Object 没有某个方法,但是呢,其它的对象有,我们可以借助 call 或 apply 用其它对象的方法来操作。
  • bind 方法传递给调用函数的参数可以逐个列出,也可以写在数组中。bind 方法与 call、apply 最大的不同就是前者返回一个绑定上下文的函数,而后者是直接执行了函数
3.19.1 手写bind
Function.prototype.myBind = function (context) { if (typeof this !== 'function') { throw new TypeError('Error') } const _this = this const args = [...arguments].slice(1) // 返回一个函数 return function F() { // 因为返回了一个函数,我们可以 new F(),所以需要判断 if (this instanceof F) { return new _this(...args, ...arguments) } return _this.apply(context, args.concat(...arguments)) } }

四、Vue.js 4.1 watch 和 computed 区别是什么?
  • watch 是监听数据,computed 是计算属性
  • computed属性只在依赖的数据发生变化时,才会重新计算,否则当多次调用computed属性时,调用的其实是缓存;watch则每调用一次就计算一次;
4.2 Vue有哪些生命周期钩子函数?分别有什么用?
  • beforeCreate :可以在这加个loading事件
  • created:在这里结束loading,还做一些初始化,实现函数自执行
  • mounted:在这里发起axios请求,拿回数据,配合路由钩子做其他事情
  • updated:监听data里面所有的数据
  • beforeDestory,destoryed:但组件已被删除,清空相关内容
4.3 Vue如何实现组件间的通信
  • 父子组件:1. 父传子,用props 2. 子传父,$emit('xxx',data) $on('xxx',function(){})
  • 爷孙组件,兄弟组件: eventBus var eventBus = new Vue(); eventBus.$emit() eventBus.$on()
  • Vuex
Vuex是专门为Vue.js开发的全局状态管理工具
4.4 Vue数据响应式怎么做到的?
  • 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty把这些属性全部转为 getter/setter。
  • 在mount时,实例了一个Watcher,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
vue面试题
4.5 Vue.set是做什么用的?
  • 当你想添加新的根级响应式属性时候用
mounted () { this.$set(this.student,"age", 24) }

4.6 Vuex你是这么用的?
  • 5个属性:state,getter,mutation,action,module
  • state的作用:类似于Vue对象里面的data,里面存放的数据是响应式的。
  • getter的作用:可以对State进行计算操作,她就是store的计算属性
  • mutation的作用:是Vuex修改state的唯一推荐方法,mutation用于修改state的数据,是同步的
  • action的作用:类似于 mutation, 不同在于:action 提交的是 mutation,而不是直接变更状态,action 可以包含任意异步操作
  • module的作用:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、getters、action.,使得结构清晰,方便管理。
4.7 Vue-Router你怎么用的?
  • Vue Router是官方的路由管理器
全局导航钩子
  • router.beforeEach(to,from,next) 作用主要是用于登录验证
  • router.beforeResolve(to, from, next),
  • router.afterEach(to, from )
组件內钩子
  • beforeRouteEnter,
  • beforeRouteUpdate,
  • beforeRouteLeave
单独路由独享组件
  • beforeEnter
4.7.1 active-class 是哪个组件的属性?嵌套路由怎么定义
  • active-class 是 vue-router 模块的 router-link 组件的属性
  • 使用 children 定义嵌套路由
4.7.2 怎么定义 vue-router 的动态路由? 怎么获取传过来的值
  • 在 router 目录下的 index.js 文件中,对 path 属性加上 /:id。
  • 使用 router 对象的 params.id 获取
4.7.3 $route和$router的区别
  • $route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
  • $router是“路由实例”对象包括了路由的跳转方法,钩子函数等。
4.7.4 指令keep-alive
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
大白话: 比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染

4.7.5 路由守卫
  • 概念:导航守卫就是路由跳转过程中的一些钩子函数。
4.7.6 hash和history的区别
  • Hash 模式只可以更改 # 后面的内容,History 模式可以通过 API 设置任意的同源 URL
  • History 模式可以通过 API 添加任意类型的数据到历史记录中,Hash 模式只能更改哈希值,也就是字符串
  • Hash 模式无需后端配置,并且兼容性好。History 模式在用户手动输入地址或者刷新页面的时候会发起 URL
    请求,后端需要配置 index.html 页面用于匹配不到静态资源的时候
4.8 vue 的双向绑定的原理是什么 vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来 劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
4.9 对MVVM框架的理解,它和其它框架(jquery)的区别是什么?哪些场景适合?
  • 一个model+view+viewModel框架,数据模型model用户操作界面view,viewModel连接这两个,
    在使用过程中,利用双向绑定技术,当Model变化时,ViewModel会自动更新,而ViewModel变化时,View也会自动变化
  • 区别:vue数据驱动,通过数据来显示视图层而不是节点操作。
  • 场景:数据操作比较多的场景,更加便捷
4.10 v-slot
  • 是对组件的扩展,通过slot插槽向组件内部指定位置传递内容,通过slot可以父子传参
4.11 v-for中的key值
  • 当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略
  • 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重排现有元素
  • 为了高效的更新虚拟DOM
4.12 v-if 和 v-show
  • v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐
五、 HTTP 5.1 HTTP状态码 2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
  • 200 (成功)服务器已经成功处理了请求。
  • 201 (已创建)请求成功并且服务器创建了新的资源。
  • 204 (无内容)服务器成功处理了请求,但是没有返回任何内容
  • 300 (多种选择)针对请求,服务器可执行多种操作。
  • 301 (永久重定向)请求的网页已永久移动到新的位置。
  • 302 (临时重定向)请求的资源已被分配了新的URI,希望用户能使用新的URI访问
  • 303 (查看其他位置)请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源
  • 304 (未修改) 自从上次请求后,请求的网页未修改过。
  • 400 (错误请求) 服务器不理解请求的语法。
  • 401 (未授权) 请求要求身份验证。
  • 403 (禁止) 服务器拒绝请求。
  • 404 (未找到) 服务器找不到请求的网页。
  • 414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
  • 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
  • 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
  • 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
  • 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
5.2 HTTP缓存有几种 2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
强制缓存和协商缓存
5.3 GET和POST请求的区别
  • GET是向服务器端请求数据,POST是向服务器提交数据。(正确的说法)
  • GET URL有长度限制的,而POST没有。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在消息体中。
  • GET 只需要一个报文,POST需要两个及以上
  • GET 幂等,POST不幂等(幂等:你发多次请求是不会改变数据库里面的东西,而POST不一定。)
5.4 Cookie LocalStorage SessionStorage Seccion 5.4.1 Cookie 和 Session的区别
  • Cookie是服务器发给客户端的一段字符串,浏览器在每次访问对应域名的时候都要带上这个字符串
  • Session 是会话,表示浏览器和服务器一段时间内的会话
  • Session是在服务器上,Cookie是在浏览器上
  • Session一般是基于Cookie实现的,把Session_ID放到Cookie里面
5.4.2 Cookie 和 LocalStorage
  • Cookie一般是4K,LocalSrotage一般是5M
  • Cookie一般是存用户信息的,LocalSrotage存储不重要的东西
  • Cookie会发送到服务器的,LocalSrotage不会
5.4.2 SessionStorage和 LocalStorage
  • LocalStorage一般不会过期,SessionStorage会在Session结束时候过期
5.4.3 如果浏览器禁用cookie,怎么办?
  • URL重写,就是把session id直接附加在URL路径的后面。
http://www.test.com/test; jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764

  • 表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。

5.5 HTTP和HTTPS的区别
  • HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
  • HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
  • HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
  • HTTP 无法加密,而HTTPS 对传输的数据进行加密
  • HTTP无需证书,而HTTPS 需要CA机构的SSL证书
5.6 HTTP 1.1 和 HTTP 2.0 的区别
  • 多路复用
    做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。
    当然HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
  • 数据压缩
    HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快
  • 服务器推送
    意思是说,当我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。
    服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。
5.7 从输入URL到页面展现中间发生了什么? 2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
1、浏览器的地址栏输入URL并按下回车。
2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
3、DNS解析URL对应的IP。
4、根据IP建立TCP连接(三次握手)。
5、HTTP发起请求。
6、服务器处理请求,浏览器接收HTTP响应。
7、渲染页面,构建DOM树。
8、关闭TCP连接(四次挥手)
5.7.1 三次握手
  • 客户端发送syn报文,并置发送序号为X
  • 服务器发送syn+ack报文,并置发送序号为Y,确认序号为X+1
  • 客户端发送ack报文,并置发送序号为Z,确认序号为Y+1
5.7.2 四次挥手
  • 主动方放送Fin+ack报文,并置发送序号为Z
  • 被动放发送ack报文,并置发送序号为Z,在确认序号为X+1
  • 被动方发送Fin +ack 报文,并置发序号为Y,在确认序号为X
  • 主动方发送Fin +ack报文,并置发送序号为X,在确认序号为Y
5.7.3 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
六、Web性能优化 6.1 DNS查询
  • 尽量减少域名,把所有的资源放在一个网站
6.2 链接TCP协议
  • 连接复用,在HTTP协议请求头里面写一个keep-alive
  • 如果是HTTP2.0 多路复用
6.3 发送HTTP请求
  • 减少cookie体积
  • CacheControl
  • 浏览器会同时发送多个请求
6.4 接受响应
  • ETag 304
  • Gzip 压缩 文件越大 效果越明显
6.5 DOCTYPE
  • 不能不写,不能写错
6.5 CSS
  • 使用CDN,增大下载的名额
  • CSS放在head,js放在body最后
七、 超纲题 7.1 JS垃圾回收 7.1.1 什么是垃圾
  • 没有被引用的对象可能是垃圾
  • 多个对象相互引用形成环也是垃圾
7.1.2 浏览器是如何找到垃圾,并回收
  • 标记-清除算法
从全局作用域开始,把所有遇到的变量都标记上, 然后被标记的变量引用了其他东西就再标记,一直标记到找不到新的东西,标记过程就结束了,最后把没标记的删除。
  • 引用计数
八、DOM 8.1 事件委托 8K版本
ul.addEventListener('click',(e)={ if(e.targer.nodeName.toLowerCase === 'li'){ console.log('点击') } })

12K+版本
ul.addEventListener('click', function(e) { var el= e.target; while (target !== ul) { if (target.tagName.toLowerCase() == 'li') { console.log('li被点击了'); break; } el= el.parentNode; } })

8.2 用mouse事件实现一个可拖曳的div
xxx.style.left 1. 一开始是空 2. 自带px,需要parseInt
var dragging = false var position = nullxxx.addEventListener('mousedown',(e)=>{ dragging = true position = [e.clientX,e.clientY] })document.addEventListener('mousemove',(e)=>{ if(dragging === false){return} let x = e.clientX let y = e.clientY const deltaX = x - position[0] const deltaY = y - position[1] const left = parseInt(xxx.style.left || 0) const top = parseInt(xxx.style.top || 0) xxx.style.left = left + deltaX + 'px' xxx.style.top = top + deltaY + 'px' position = [x,y] })document.addEventListener('mouseup',()=>{ dragging = false })

九、安全押题 9.1 什么是XSS攻击,如何预防?
  • 恶意代码被执行,这就是XSS
div.innerHTML = userComment //userComment 内容是

  • 预防
    1. 不要使用innerHTML,改成innerText
    2. 如果一定用innerHTML,就需要进行字符过滤
      • 把 < 改为< ,
      • 把 > 改为> ,
      • 把 & 改为&
      • 把 ' 改为'
      • 把 " 改为"
  • 代码 div.innerHTML = userComment.replace(/>/g,'< ').replace...
9.2 CSRF攻击?如何预防?
2019-07-03|2019-07-03 初级前端面试题个人汇总
文章图片
十、算法 10.1 冒泡排序
function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]) {// 相邻元素两两对比 var temp = arr[j+1]; // 元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; }

10. 2 快速排序
function quickSort(arr) { if(arr.length <=1){ return arr } let left = [] let right = [] let current = arr.splice(0,1) for(let i = 0; i

    推荐阅读