面试题

HTML

1.必考:你是如何理解 HTML 语义化的?

i.举例法

HTML 语义化就是使用正确的标签(总结)段落就写 p 标签,标题就写 h1 标签,文章就写article标签,视频就写video标签,等等。

ii.阐述法

首先讲以前的后台开发人员使用table布局,然后讲美工人员使用div+css布局,最后讲专业的前端会使用正确的标签进行页面开发。

2.meta viewport 是做什么用的,怎么写?

举例法

<meta name="viewport" content="width=device-width, initial-scale=1, 	maximum-scale=1, minimum-scale=1">
<meta>:文档级元数据元素
元数据类型:
Name:如果设置了 name 属性,meta 元素提供的是文档级别(document-level)的元数据,应用于整个页面。
http-equiv:如果设置了 http-equiv 属性,meta 元素则是编译指令,提供的信息与类似命名的HTTP头部相同。
Charset:meta 元素是一个字符集声明,告诉文档使用哪种字符编码。
itemprop:meta 元素提供用户定义的元数据。

属性:
Content:此属性包含http-equiv 或name 属性的值,具体取决于所使用的值。
Charset: 这个属性声明了文档的字符编码。如果使用了这个属性,其值必须是与ASCII大小写无关(ASCII case-insensitive)的"utf-8"。
http-equiv: 定义了一个编译指示指令。

3.你用过哪些 HTML 5 标签?

举例法 / 需附加说明属性

根元素
<html>代表 HTMLXHTML 文档的根。其他所有元素必须是这个元素的子节点。
文档元数据
<head>代表关于文档元数据的一个集合,包括脚本或样式表的链接或内容。

<title>定义文档的标题,将显示在浏览器的标题栏或标签页上。该元素只能包含文本,包含的标签不会被解释。

<base>定义页面上相对 URL 的基准 URL<link>用于链接外部的 CSS 到该文档。

<meta>定义其他 HTML 元素无法描述的元数据。

<style>用于内联 CSS。

脚本
<script>定义一个内联脚本或链接到外部脚本。脚本语言是 JavaScript。
<noscript>定义当浏览器不支持脚本时显示的替代文字。
<template> 通过 JavaScript 在运行时实例化内容的容器。
章节
<body>代表 HTML 文档的内容。在文档中只能有一个 <body> 元素。
<section> 定义文档中的一个章节。

<nav> 定义只包含导航链接的章节。

<article> 定义可以独立于内容其余部分的完整独立内容块。

<aside> 定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。

<h1>,<h2>,<h3>,<h4>,<h5>,<h6>标题元素实现了六层文档标题,<h1> 是最大的标题,<h6> 是最小的标题。标题元素简要地描述章节的主题。

<header> 定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。

<footer> 定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。

<address>定义包含联系信息的一个章节。

<main> 定义文档中主要或重要的内容。

组织内容

<p> 定义一个段落。

<hr> 代表章节、文章或其他长内容中段落之间的分隔符。

<pre> 代表其内容已经预先排版过,格式应当保留 。

<blockquote> 代表引用自其他来源的内容。

<ol> 定义一个有序列表。

<ul> 定义一个无序列表。

<li> 定义列表中的一个列表项。

<dl> 定义一个定义列表(一系列术语和其定义)。

<dt> 代表一个由下一个 <dd> 定义的术语。

<dd> 代表出现在它之前术语的定义。

<figure> 代表一个和文档有关的图例。

<figcaption> 代表一个图例的说明。

<div> 代表一个通用的容器,没有特殊含义。

文字形式

<a> 代表一个链接到其他资源的超链接 。

<em> 代表强调 文字。

<strong> 代表特别重要 文字。

<small> 代表注释 ,如免责声明、版权声明等,对理解文档不重要。

<s> 代表不准确或不相关 的内容。

<cite> 代表作品标题 。

<q> 代表内联的引用 。

<dfn> 代表一个术语包含在其最近祖先内容中的定义 。

<abbr> 代表省略 或缩写 ,其完整内容在 title 属性中。

<data> 关联一个内容的机器可读的等价形式 (该元素只在 WHATWG 版本的 HTML 标准中,不在 W3C 版本的 HTML5 标准中)。

<time> 代表日期 和时间 值;机器可读的等价形式通过 datetime 属性指定。

<code> 代表计算机代码 。

<var> 代表代码中的变量 。

<samp> 代表程序或电脑的输出 。

<kbd> 代表用户输入 ,一般从键盘输出,但也可以代表其他输入,如语音输入。

<sub>,<sup> 分别代表下标 和上标 。

<i> 代表一段不同性质 的文字,如技术术语、外文短语等。

<b> 代表一段需要被关注 的文字。

<u> 代表一段需要下划线呈现的文本注释,如标记出拼写错误的文字等。

<mark> 代表一段需要被高亮的引用 文字。

<ruby> 代表被ruby 注释 标记的文本,如中文汉字和它的拼音。

<rt> 代表ruby 注释 ,如中文拼音。

<rp> 代表 ruby 注释两边的额外插入文本 ,用于在不支持 ruby 注释显示的浏览器中提供友好的注释显示。

<bdi> 代表需要脱离 父元素文本方向的一段文本。它允许嵌入一段不同或未知文本方向格式的文本。

<bdo> 指定子元素的文本方向 ,显式地覆盖默认的文本方向。

<span> 代表一段没有特殊含义的文本,当其他语义元素都不适合文本时候可以使用该元素。

<br> 代表换行 。

<wbr> 代表建议换行 (Word Break Opportunity) ,当文本太长需要换行时将会在此处添加换行符。

编辑

<ins> 定义增加 到文档的内容。

<del> 定义从文档移除 的内容。

嵌入内容

<img> 代表一张图片 。

<iframe> 代表一个内联的框架 。

<embed> 代表一个嵌入 的外部资源,如应用程序或交互内容。

<object> 代表一个外部资源 ,如图片、HTML 子文档、插件等。

<param> 代表 <object> 元素所指定的插件的参数 。

<video> 代表一段视频 及其视频文件和字幕,并提供了播放视频的用户界面。

<audio> 代表一段声音 ,或音频流 。

<source><video><audio> 这类媒体元素指定媒体源 。

<track><video><audio> 这类媒体元素指定文本轨道(字幕) 。

<canvas> 代表位图区域 ,可以通过脚本在它上面实时呈现图形,如图表、游戏绘图等。

<map><area> 元素共同定义图像映射 区域。

<area><map> 元素共同定义图像映射 区域。

<svg> 定义一个嵌入式矢量图 。

<math> 定义一段数学公式 。

表格

<table> 定义多维数据 。

<caption> 代表表格的标题 。

<colgroup> 代表表格中一组单列或多列 。

<col> 代表表格中的列 。

<tbody> 代表表格中一块具体数据 (表格主体)。

<thead> 代表表格中一块列标签 (表头)。

<tfoot> 代表表格中一块列摘要 (表尾)。

<tr> 代表表格中的行 。

<td> 代表表格中的单元格 。

<th> 代表表格中的头部单元格 。

表单

<form> 代表一个表单 ,由控件组成。

<fieldset> 代表控件组 。

<legend> 代表 <fieldset> 控件组的标题 。

<label> 代表表单控件的标题 。

<input> 代表允许用户编辑数据的数据区 (文本框、单选框、复选框等)。

<button> 代表按钮 。

<select> 代表下拉框 。

<datalist> 代表提供给其他控件的一组预定义选项 。

<optgroup> 代表一个选项分组 。

<option> 代表一个 <select> 元素或 <datalist> 元素中的一个选项

<textarea> 代表多行文本框 。

<keygen> 代表一个密钥对生成器 控件。

<output> 代表计算值 。

<progress> 代表进度条 。

<meter> 代表滑动条 。

交互元素

<details> 代表一个用户可以(点击)获取额外信息或控件的小部件 。

<summary> 代表 <details> 元素的综述 或标题 。

<menuitem> 代表一个用户可以点击的菜单项。

<menu> 代表菜单。

CSS

1.必考:两种盒模型分别说一下。

先说两种盒模型分别怎么写,具体到代码。然后说你平时喜欢用border box,因为更好用。

box-sizing: conent-box; 将盒子设置为标准模型(盒子默认为标准模型)
box-sizing: border-box; 将盒子设置为 IE 模型(也叫做怪异盒子)

标准模型:box-sizing: conent-box;

content-box {
  width: 100px;
  height: 100px;
  border: 50px solid;
  padding: 50px;
}

它在页面中实际占有的宽高为:(50px * 2)(border) + (50px * 2)(padding) + 100px(content) = 300px在这里插入图片描述

怪异盒子(IE):box-sizing: border-box;

content-box {
  width: 100px;
  height: 100px;
  border: 50px solid;
  padding: 50px;
}

它在页面中实际占有的宽高为:100px,但可以看到,由于 border + padding 已经等于 100px 了,所以这里 content 已经被压缩到只剩 0 了,实际盒子看起来已经无法很好的存放 content 内容了:
在这里插入图片描述
(tip:为了防止盒子在页面中实际占有面积超出预计以出现横向滚动条,通常会有开发者将最外部的盒子设为 IE 模型 )

真正的问题

你以为到这里就完了吗?不不不,接下来才是问题的开始,面试官不会问些不痛不痒的问题,又不能考察水平,又浪费时间。
这个时候通常会接着问外边距重叠,或者是 BFC 相关的问题了。
那么什么是边距重叠呢?我们来看个例子

外边距重叠
快格式上下文

3.必考:flex 怎么用,常用属性有哪些

flex 的核心的概念就是容器和轴。容器包括外层的父容器和内层的子容器,轴包括主轴和交叉轴,可以说 flex 布局的全部特性都构建在这两个概念上。一共 12 个,父容器、子容器各 6 个。
父容器:通过给父级设置display:flex 开启容器,子级会根据容器规则排序
子容器:通过flex,order,align-self和伸缩方式调整。

在这里插入图片描述

4.必考:BFC 是什么?(块级格式上下文)

背 BFC 触发条件,MDN 写了。(display 就是创建一个bfc,但BFC类型很多,下面就是BFC不同的类型)
但是不用全部背下来,面试官只知道其中几个:

  1. 浮动元素(元素的 float 不是 none)
  2. 绝对定位元素(元素的 position 为 absolute 或 fixed)
  3. 行内块元素
  4. overflow 值不为 visible 的块元素
  5. 弹性元素(display为 flex 或 inline-flex元素的直接子元素)

5.CSS 选择器优先级

背人云亦云的答案(错答案、已过时):https://www.cnblogs.com/xugang/archive/2010/09/24/1833760.html
看面试官脸色行事
方方给的三句话
越具体优先级越高
同样优先级写在后面的覆盖写在前面的
!important 优先级最高,但是要少用

6.清除浮动说一下

背代码
.clearfix:after{
content: ‘’;
display: block; /或者 table/
clear: both;
}
.clearfix{
zoom: 1; /* IE 兼容*/
}

原生JS

1.必考:ES 6 语法知道哪些,分别怎么用?

举例法

let --  let 语句声明一个块级作用域的本地变量,并且可以将其初始化为一个值。
		varlet 的不同之处在于后者是在编译时才初始化(编译前会存在于暂存死区)
const -- 常量声明一个块级作用域,不会变为全局window对象的属性。

箭头函数 -- 箭头函数 比函数表达式简洁,没有自己的thisthis默认指向上一个this的作用域链

Promise -- Promise 对象用于表示一个异步操作的最终完成resolve (或失败reject)和结果值。

展开操作符 -- 将数组从语法层面上展开分成参数

默认参数 -- 函数的参数默认是undefined,数组是NAN,可以通过multiply方法设置默认参数

解构赋值 -- 可以将属性/值从对象/数组中取出,赋值给其他变量。(解析以后赋值)

import -- 静态的import 语句用于导入由另一个模块导出的绑定。
export -- 导出模块,以便其他程序可以通过 import 语句使用它们,导出的模块都处于严格模式。 export语句不能用在嵌入式脚本中。
			存在两种 exports 导出方式:
				命名导出(每个模块包含任意数量)
					export { variable1 as name1, variable2 as name2,, nameN };
				默认导出(每个模块包含一个)
					export default expression;

在这里插入图片描述
见方方整理的列表

2.必考 Promise、Promise.all、Promise.race 分别怎么用?

(1)背代码 Promise 用法

 function fn(){
     return new Promise((resolve, reject)=>{
         成功时调用 resolve(数据)
         失败时调用 reject(错误)
     })
 }
 fn().then(success, fail).then(success2, fail2)

(2)背代码 Promise.all 用法

 Promise.all([promise1, promise2]).then(success1, fail1)
promise1和promise2都成功才会调用success1

(3)背代码 Promise.race 用法

 Promise.race([promise1, promise2]).then(success1, fail1)
promise1和promise2只要有一个成功就会调用success1;
promise1和promise2只要有一个失败就会调用fail1;

总之,谁第一个成功或失败,就认为是race的成功或失败。

3.必考:手写函数防抖和函数节流

(1)背代码 - 节流

 // 节流(一段时间执行一次之后,就不执行第二次)
 function throttle(fn, delay){
     let canUse = true
     return function(){
         if(canUse){
             fn.apply(this, arguments)
             canUse = false
             setTimeout(()=>canUse = true, delay)
         }
     }
 }

 const throttled = throttle(()=>console.log('hi'))
 throttled()
 throttled()

注意,有些地方认为节流函数不是立刻执行的,而是在冷却时间末尾执行的(相当于施法有吟唱时间),那样说也是对的。

(2)背代码 - 防抖

 // 防抖(一段时间会等,然后带着一起做了)
 function debounce(fn, delay){
     let timerId = null
     return function(){
         const context = this
         if(timerId){window.clearTimeout(timerId)}
         timerId = setTimeout(()=>{
             fn.apply(context, arguments)
             timerId = null
         },delay)
     }
 }
 const debounced = debounce(()=>console.log('hi'))
 debounced()
 debounced()

4.必考:手写AJAX

(1)背代码,完整版

 var request = new XMLHttpRequest()
 request.open('GET', '/a/b/c?name=ff', true);
 request.onreadystatechange = function () {
   if(request.readyState === 4 && request.status === 200) {
     console.log(request.responseText);
   }};
 request.send();

(2)背代码,简化版

 var request = new XMLHttpRequest()
 request.open('GET', '/a/b/c?name=ff', true)
 request.onload = ()=> console.log(request.responseText)
 request.send()

5.必考:这段代码里的 this 是什么?

(1)背代码

fn() -- 函数调用,this指向全局对象
this => window/global
obj.fn() -- 对象的方法调用,this指向对象
this => obj
fn.call(xx) -- call指定this指向
this => xx
fn.apply(xx) -- apply指定this指向
this => xx
fn.bind(xx) -- bind指定this指向
this => xx
new Fn() -- 构造函数,this会指向构造出的新对象
this => 新的对象
fn = ()=> {} -- 箭头函数,this指向外部
this => 外面的 this

(2)看调用

《this 的值到底是什么?一次说清楚》

6.必考:闭包/立即执行函数是什么?

闭包
立即执行函数

7.必考:什么是 JSONP,什么是 CORS,什么是跨域?

饥人谷系统班全都有讲,没有报名的同学自己搜文章看
JSONP https://zhuanlan.zhihu.com/p/22600501
CORS https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

8.常考:async/await 怎么用,如何捕获异常?

阮一峰的书讲了
方方的视频课讲了 最后一节。

9.常考:如何实现深拷贝?

背代码,要点:

递归
判断类型
检查环(也叫循环引用)
需要忽略原型

10.常考:如何用正则实现 trim()?

背代码

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

11.常考:不用 class 如何实现继承?用 class 又如何实现?

背代码,不用 class 这样实现

 function Animal(color){
     this.color = color
 }
 Animal.prototype.move = function(){} // 动物可以动
 function Dog(color, name){
     Animal.call(this, color) // 或者 Animal.apply(this, arguments)
     this.name = name
 }
 // 下面三行实现 Dog.prototype.__proto__ = Animal.prototype
 function temp(){}
 temp.prototype = Animal.prototype
 Dog.prototype = new temp()

 Dog.prototype.constuctor = Dog // 这行看不懂就算了,面试官也不问
 Dog.prototype.say = function(){ console.log('汪')}

 var dog = new Dog('黄色','阿黄')

背代码,用 class 就简单了

 class Animal{
     constructor(color){
         this.color = color
     }
     move(){}
 }
 class Dog extends Animal{
     constructor(color, name){
         super(color)
         this.name = name
     }
     say(){}
 }

12.常考:如何实现数组去重?

计数排序变形,背代码
使用 Set(面试已经禁止这种了,因为太简单)
使用 WeakMap

13.放弃:== 相关题目(反着答)

不要背,记不住,太复杂且没有规律

14.送命题:手写一个 Promise

提前写一遍,放在博客里,参考 https://juejin.im/post/5aafe3edf265da238f125c0a

DOM

1.必考:事件委托

错误版(但是可能能过)

 ul.addEventListener('click', function(e){
     if(e.target.tagName.toLowerCase() === 'li'){
         fn() // 执行某个函数
     }
 })

bug 在于,如果用户点击的是 li 里面的 span,就没法触发 fn,这显然不对。

高级版

 function delegate(element, eventType, selector, fn) {
     element.addEventListener(eventType, e => {
       let el = e.target
       while (!el.matches(selector)) {
         if (element === el) {
           el = null
           break
         }
         el = el.parentNode
       }
       el && fn.call(el, e, el)
     })
     return element
   }

思路是点击 span 后,递归遍历 span 的祖先元素看其中有没有 ul 里面的 li。

2.曾考:用 mouse 事件写一个可拖曳的 div

参考代码:https://jsbin.com/munuzureya/edit?html,js,output

HTTP

1.必考:HTTP 状态码知道哪些?分别什么意思?

2xx 表示成功
3xx 表示需要进一步操作
4xx 表示浏览器方面出错
5xx 表示服务器方面出错

完整参考 http://www.runoob.com/http/http-status-codes.html

2.大公司必考:HTTP 缓存有哪几种?

需要详细的了解 ETag、CacheControl、Expires 的异同
参考 https://imweb.io/topic/5795dcb6fb312541492eda8c
答题要点:

ETag 是通过对比浏览器和服务器资源的特征值(如MD5)来决定是否要发送文件内容,如果一样就只发送 304(not modified)
Expires 是设置过期时间(绝对时间),但是如果用户的本地时间错乱了,可能会有问题 CacheControl: max-age=3600
是设置过期时长(相对时间),跟本地时间无关。

3.必考:GET 和 POST 的区别

错解,但是能过面试

GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被加入收藏栏,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GETPOST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。

正解

就一个区别:语义——GET 用于获取资源,POST 用于提交资源。

想装逼请参考 https://zhuanlan.zhihu.com/p/22536382

4.Cookie V.S. LocalStorage V.S. SessionStorage V.S. Session

(1)Cookie V.S. LocalStorage
主要区别是 Cookie 会被发送到服务器,而 LocalStorage 不会
Cookie 一般最大 4k,LocalStorage 可以用 5Mb 甚至 10Mb(各浏览器不同)

(2)LocalStorage V.S. SessionStorage
LocalStorage 一般不会自动过期(除非用户手动清除),而 SessionStorage 在回话结束时过期(如关闭浏览器)

(3)Cookie V.S. Session
Cookie 存在浏览器的文件里,Session 存在服务器的文件里
Session 是基于 Cookie 实现的,具体做法就是把 SessionID 存在 Cookie 里

框架 Vue

1.必考:watch 和 computed 和 methods 区别是什么?

(1)思路:

先翻译单词,再阐述作用,最后强行找不同。

(2)要点:

1)computed 和 methods 相比,
最大区别是 computed 有缓存:如果 computed 属性依赖的属性没有变化,那么 computed 属性就不会重新计算。methods 则是看到一次计算一次。
(2)watch 和 computed 相比,
computed 是计算出一个属性(废话),而 watch 则可能是做别的事情(如上报数据)

2.必考:Vue 有哪些生命周期钩子函数?分别有什么用?

1)钩子在文档全都有,看红色的字。
生命周期钩	子组件状态	最佳实践 
beforeCreate
实例初始化之后,this指向创建的实例,不能访问到data、computed、watch、methods上的方法和数据
<常用于初始化非响应式变量>
            
created
实例创建完成,可访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到$el属性,$ref属性内容为空数组
<常用于简单的ajax请求,页面的初始化>
            
            
beforeMount
在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数 
<>
            
            
mounted
实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问 
<常用于获取VNode信息和操作,ajax请求>
            
            
beforeupdate 
响应式数据更新时调用,发生在虚拟DOM打补丁之前 
<适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器>
            
            
updated 
虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作 
<避免在这个钩子函数中操作数据,可能陷入死循环>
            
            
beforeDestroy 实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例 
<常用于销毁定时器、解绑全局事件、销毁插件对象等操作>
            
            
destroyed 实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 
<>

注意:
created阶段的ajax请求与mounted请求的区别:前者页面视图未出现,如果请求信息过多,页面会长时间处于白屏状态
mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染

(2)把名字翻译一遍就是满分
(3)要特别说明哪个钩子里请求数据,答案是 mounted

在这里插入图片描述

3.必考:Vue 如何实现组件间通信?

1.父子通信
2.爷孙通信
3.任意通信eventBus
4.任意通信Vuex

v-on -- 缩写:@  参数:event
父子组件:使用 v-on 通过事件通信
父子组件的关系可以总结为 prop 向下传递,事件向上传递。
父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息

1. 父组件向子组件进行传值
<template>
  <div>
    父组件:
    <input type="text" v-model="name">
    <br>
    <br>
    <!-- 引入子组件 -->
    <child :inputName="name"></child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    }
  }
</script>
--------------------------------------------------------
<template>
  <div>
    子组件:
    <span>{{inputName}}</span>
  </div>
</template>
<script>
  export default {
    // 接受父组件的值
    props: {
      inputName: String,
      required: true
    }
  }
</script>
---------------------
1.2子组件向父组件传值
<template>
  <div>
    子组件:
    <span>{{childValue}}</span>
    <!-- 定义一个子组件传值的方法 -->
    <input type="button" value="点击触发" @click="childClick">
  </div>
</template>
<script>
  export default {
    data () {
      return {
        childValue: '我是子组件的数据'
      }
    },
    methods: {
      childClick () {
        // childByValue是在父组件on监听的方法
        // 第二个参数this.childValue是需要传的值
        this.$emit('childByValue', this.childValue)
      }
    }
  }
</script>
------------------------------------------------------------
<template>
  <div>
    父组件:
    <span>{{name}}</span>
    <br>
    <br>
    <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
    <child v-on:childByValue="childByValue"></child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    },
    methods: {
      childByValue: function (childValue) {
        // childValue就是子组件传过来的值
        this.name = childValue
      }
    }
  }
</script>
----------------
2.爷孙组件:使用两次 v-on 通过爷爷爸爸通信,爸爸儿子通信实现爷孙通信
A组件>B组件>C组件
例子:A组件中打开B组件,再从B组件打开C组件,然后C组件中方法触发A组件中的某条数据更新
简要的讲就是,$attrs可以获取父作用域传入的值(不包括props中的),$listeners相当于父作用域的事件监听器,那我们就可以用这两个属性实现祖孙之间的数据通信


-----------------
任意组件:使用 eventBus = new Vue() 来通信,eventBus.$on 和 eventBus.$emit 是主要API
	非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。

//公共bus.js
//bus.js
import Vue from 'vue'
export default new Vue()
// A组件
<template>
  <div>
    A组件:
    <span>{{elementValue}}</span>
    <input type="button" value="点击触发" @click="elementByValue">
  </div>
</template>
<script>
  // 引入公共的bug,来做为中间传达的工具
  import Bus from './bus.js'
  export default {
    data () {
      return {
        elementValue: 4
      }
    },
    methods: {
      elementByValue: function () {
        Bus.$emit('val', this.elementValue)
      }
    }
  }
</script>
-------------------------------------------------------------
// B组件
<template>
  <div>
    B组件:
    <input type="button" value="点击触发" @click="getData">
    <span>{{name}}</span>
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        name: 0
      }
    },
    mounted: function () {
      var vm = this
      // 用$on事件来接收参数
      Bus.$on('val', (data) => {
        console.log(data)
        vm.name = data
      })
    },
    methods: {
      getData: function () {
        this.name++
      }
    }
  }
</script>

任意组件:使用 Vuex 通信

4.必考:Vue 数据响应式怎么做到的?

答案在文档《深入响应式原理》

要点

使用 Object.defineProperty 把这些属性全部转为 getter/setter

Vue 不能检测到对象属性的添加或删除,解决方法是手动调用 
Vue.set 或者 this.$set

5.必考:Vue.set 是做什么用的?

见上一题

6.Vuex 你怎么用的?

(1)背下文档第一句:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

说出核心概念的名字和作用:

State
Getter
Mutation
Action
Module

7.VueRouter 你怎么用的?

(1)背下文档第一句:

Vue Router 是 Vue.js 官方的路由管理器。

(2)说出核心概念的名字和作用:

History 模式/导航守卫/路由懒加载

(3)说出常用 API:

router-link
router-view
this.$router.push
this.$router.replace
this.$route.params
 this.$router.push('/user-admin')
 this.$route.params

8.路由守卫是什么?

看官方文档的例子,背里面的关键的话

框架 React

1.必考:受控组件 V.S. 非受控组件

 <FInput value={x} onChange={fn}/> 受控组件
 <FInput defaultValue={x} ref={input}/> 非受控组件

区别受控组件的状态由开发者维护,非受控组件的状态由组件自身维护(不受开发者控制)

2.必考:React 有哪些生命周期函数?分别有什么用?(Ajax 请求放在哪个阶段?)

答题思路跟 Vue 的一样
(1) 钩子在文档里,蓝色框框里面的都是生命周期钩子
(2) 把名字翻译一遍就是满分
(3) 要特别说明哪个钩子里请求数据,答案是 componentDidMount

3.必考:React 如何实现组件间通信?

父子靠 props 传函数 爷孙可以穿两次 props 任意组件用 Redux(也可以自己写一个 eventBus)

4.必考:shouldComponentUpdate 有什么用?

要点:用于在没有必要更新 UI 的时候返回 false,以提高渲染性能
参考:http://taobaofed.org/blog/2016/08/12/optimized-react-components/

5.必考:虚拟 DOM 是什么?

要点:虚拟 DOM 就是用来模拟 DOM 的一个对象,这个对象拥有一些重要属性,并且更新 UI 主要就是通过对比(DIFF)旧的虚拟 DOM
树 和新的虚拟 DOM 树的区别完成的。
参考:http://www.alloyteam.com/2015/10/react-virtual-analysis-of-the-dom/

6.必考:什么是高阶组件?

(1)要点:文档原话——高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。
(2)举例:React-Redux 里 connect 就是一个高阶组件,比如
connect(mapState)(MyComponent)
接受组件 MyComponent,返回一个具有状态的新 MyComponent 组件。

7.React diff 的原理是什么?

看你记忆力了:https://imweb.io/topic/579e33d693d9938132cc8d94

8.必考 Redux 是什么?

(1)背下文档第一句:

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

重点是『状态管理』。

(2)说出核心概念的名字和作用:

Action/Reducer/Store/单向数据流

说出常用 API:

store.dispatch(action)/store.getState()

9.connect 的原理是什么?

react-redux 库提供的一个 API,connect 的作用是让你把组件和store连接起来,产生一个新的组件(connect
是高阶组件) 参考:https://segmentfault.com/a/1190000017064759

TypeScript

1.never 类型是什么?

不应该出现的类型
尤雨溪的答案:https://www.zhihu.com/question/354601204/answer/888551021

2.TypeScript 比起 JavaScript 有什么优点?

提供了类型约束,因此更可控、更容易重构、更适合大型项目、更容易维护

Webpack

1.必考:有哪些常见 loader 和 plugin,你用过哪些?

2.英语题:loader 和 plugin 的区别是什么?

3.必考:如何按需加载代码?

4.必考:如何提高构建速度?

5.转义出的文件过大怎么办?

上面五题请看这个不错的参考:https://zhuanlan.zhihu.com/p/44438844

安全

1.必考:什么是 XSS?如何预防?

比较复杂,看我的文章 https://zhuanlan.zhihu.com/p/22500730

2.必考:什么是 CSRF?如何预防?

比较复杂,看若愚的文章 https://zhuanlan.zhihu.com/p/22521378

开放题目

1.必考:你遇到最难的问题是怎样的?

要点:一波三折。参考 https://www.zhihu.com/question/35323603

2.你在团队的突出贡献是什么?

把小事说大。

3.最近在关注什么新技术

书、博客、推特、知乎,不要说 CSDN、百度。

4.有没有看什么源码,看了后有什么记忆深刻的地方,有什么收获

看过源码说源码,推荐看 underscore.js 的源码 没看过源码就说同事的代码,代码烂就说哪里烂,代码好就说哪里好
收获:命名规范、设计模式

刁钻题目

1.代码

 [1,2,3].map(parseInt)
 
答案
 1
 NaN
 NaN

2.代码

 var a = {name: 'a'}
 a.x = a = {}
问 a.x 是多少?
答案:
undefined

3.(a ==1 && a== 2 && a==3) 可能为 true 吗?

(1)利用 == 会调用 valueOf() 的特性

 var a = {
  value: 1,
  valueOf(){
   return this.value++
  }
 }
 a ==1 && a== 2 && a==3 // true

(2)利用 a 会读取 window.a 的特性

 var value = 1; 
 Object.defineProperty(window, 'a', {
     get(){
         return value++;
     }
 })
 a ==1 && a== 2 && a==3 // true
 // 或者 
 a ===1 && a=== 2 && a===3 // true

超纲题

1.JS 垃圾回收机制

(1)看图讲解

	什么是垃圾
	如何捡垃圾(遍历和计数,只是不同的算法而已)
	前端又有其特殊性(JS进程和DOM进程)

(2)更深入一些的讲解

2. Eventloop 说一下

 setTimeout(function () {
     console.log(4);
 }, 0);
 new Promise(function (resolve) {
     console.log(1);
     resolve();
     console.log(2);
 }).then(function () {
     console.log(5);
 });

 console.log(3);
 1
 2
 3
 5
 4

(1)肤浅理解:『一会儿』和『尽快』异步任务

(2)详细理解:Eventloop 是个啥?

(3)浏览器有 Eventloop 吗?

(4)每个 API 对应哪个任务队列?

	setTimeout
	setImmediate(浏览器没有)
	process.nextTick(浏览器没有)
	MutationObserver(Node 没有)
	promise.then
	await

(5)这种题目尽量说思路,因为你不可能通过眼睛看出结果(必须画图)

 async function async1() {
     console.log(1);
     await async2();
     console.log(2);
 }
 async function async2() {
     console.log(3)
 }

 async1();

 new Promise(function (resolve) {
     console.log(4);
     resolve();
 }).then(function () {
     console.log(5);
 });
 1
 3
 4
 2
 5

注意:这一题的答案不唯一,在 Node.js 和 Chrome 的结果不一样,甚至在 Chrome
上也是时而这个答案,时而那个答案。所以还是说思路最重要。

个性化题目

  • PWA
  • echarts.js / d3.js
  • three.js
  • flutter
  • SSR

做个 hello world 基本就能应付面试了,如果怕应付不了,就再做个复杂点的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Supernova_gu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值