这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
是时候寄出失传已久的——面向面试复习法!
目录:
- HTML篇
- CSS篇
- JS篇
- DOM篇
- HTTP篇
- Vue2篇
- 安全篇
- 浏览器兼容篇
一. HTML 篇
1. 什么是 HTML 语义化?
答:就是使用恰当语义的 HTML 标签,比如段落用 <p>
,边栏用 <aside>
,主要内容用 <main>
,页眉用 <header>
,这样能让人和机器都能快速理解网页内容。
2. meta viewport 是做什么用的,怎么写?
写法:<meta name="viewport" content="width=device-width, initial-scale=1.0">
用处:控制页面在移动端不要缩小显示。
3. 你用过哪些 HTML5 标签?
答:内容相关的有页眉 <header>
,内容 <main>
,边栏 <aside>
,脚注 <footer>
等。
功能相关的有 <canvas>
,<video>
等。
4. H5 是什么?
答:H5 != HTML5,H5是移动端页面,不是一定要用了 HTML5 语法的页面才是 H5。
二. CSS篇
1. 说一说两种盒模型
答:content-box(W3C盒模型)的宽度 == 内容区宽度
border-box(IE盒模型)的宽度 == 内容区宽度 + padding 宽度 + border 宽度
通过 box-sizing 属性切换两种盒模型
2. 如何水平居中?如何垂直居中?
水平居中:
- 内联元素水平居中:在父元素上设置 text-align : center;
- 块级元素水平居中:margin : 0 auto;
垂直居中:
3. Flex 怎么用?常见的属性有哪些?
4. BFC 是什么?
答:BFC 就是块格式化上下文。
举例:如果给一个 div 写一个 overflow: hidden;(清除浮动)那么这个div里面的浮动元素就会被 div 包裹起来。
BFC 形成的条件:
- 根元素 html
- 浮动
- 绝对定位、固定定位
- overflow 除了默认值(visible)以外的值 :hidden、auto、scroll
- display : inline-block
- flex item
- 等等
有一个巧记技巧:当元素不在正常流里,元素内部可以包含文字,并且文字是从左往右写,会自动换行的,这种时候就会创建一个 BFC。上面提到的形成条件基本都符合这个逻辑!
5. CSS 选择器优先级?
权重法(CSS2):行内样式是1000 > id选择器是100 > 类选择器是10 > 元素选择器是1
更准确的判断法(CSS3):
- 选择器越具体(权重之和越大)优先级越高
- 写在后面的 CSS 覆盖前面的 CSS
- !important 优先级最高,但是建议少用。
6. 清除浮动的代码?
父元素添加如下代码,里面的子元素就清除浮动了:
.clearfix::after {
content: ""; // 空串
display: block; // 显示为块级元素
clear: both; // 清除两侧浮动的影响
}
.clearfix {
zoom: 1; // IE兼容
}
或者直接:overflow: hidden; 但不建议用这个。
三. JS 篇
1. ES6 语法知道哪些?怎么用?
2. Promise 分别怎么用?
Promise 的用法之 then 的用法:
$.ajax(...).then(成功函数, 失败函数)
链式 then 的用法:
$.ajax(...).then(成功函数1, 失败函数1).then(成功函数2, 失败函数2)
其他方法,例如 Promise.all、Promise.race,建议直接通读:
3. 如何自己生成 Promise 对象
// 背代码咯
function fn(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
// resolve() 或者 reject()
}, 3000)
})
}
// 然后我们就可以 then 了
fn().then(...)
4. async/await 语法了解吗?目的是什么?
目的:把异步代码写成同步代码
// 老的写法(异步):
function fn() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve('哈哈哈')
}, 3000)
})
}
fn().then((res) => {
res === '哈哈哈' // true
})
// 新的写法(同步):
async function fn2() {
var res = await fn();
res === '哈哈哈' // true
}
5. 手写函数防抖和函数节流
节流函数
可以把它理解成游戏中的CD冷却时间,当技能在冷却时间内的时候,我们就不能使用该技能。
function fn() {
// 游戏技能
}
var cd = false; // 是否冷却中
button.onclick = function() {
if (cd) {
// 不能使用技能
} else {
fn(); // 使用技能
cd = true; // 进入冷却时间
var timerId = setTimeout(() => {
cd = false
}, 3000) // 3秒后技能才可用
}
}
防抖函数
我们想象一个情景:当用户输入一段数据后我们要去对数据进行验证,但是如果不间断的进行验证会浪费我们的计算机资源。所以我们就想等用户输入数据后,2s 后才进行验证,若 2s 间用户更新了输入的数据,那么 2s 将重新计时。
function fn() {
// 要执行的代码
}
var timerId = null;
button.onclick = function() {
if (timerId) {
clearTimeout(timerId); // 停止之前的计时
}
timerId = setTimeout(() => { // 重新计时
fn();
timerId = null;
}, 2000)
}
6. 手写 Ajax
7. 代码中的 this 指向什么?
- fn() 里面的 this 就是 window
- obj.fn() 里面的 this 就是 obj
- new Fn() 里面的 this 就是新生成的对象
- () => {} 里面的 this 跟这个箭头函数外面的 this 一样
- fn.call(xx) 里面的 this 就是 xx
- fn.apply(xx) 里面的 this 就是 xx
- fn.bind(xx) 里面的 this 就是 xx
举例:
var obj = {
foo: function() {
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
8. 闭包是什么?立即执行函数是什么?
9. 什么是跨域?什么 JSONP?什么是 CORS?
10. JS 有哪些数据类型?
答:String, Number, Boolean, null, undefined, Symbol, BigInt 共 7 种基础数据类型,外加一种引用类型:Object。
11. 如何实现深拷贝?
JSON法(缺点多,比如 a 里面不能有函数):
var a = {...}
var b = JSON.parse(JSON.stringify(a))
递归拷贝法:
function cloneDeep(obj, map = new WeakMap()) {
if (obj && typeof obj === 'object') {
if (map.has(obj)) return map.get(obj);
const cloneObj = Array.isArray(obj) ? [] : {};
map.set(obj, cloneObj);
for (const key in obj) {
cloneObj[key] = cloneDeep(obj[key], map);
}
return cloneObj;
}
return obj;
}
12. 如何实现数组去重
Set 去重:
var a = [3, 4, 6, 3, 5, 4]
Array.from(new Set(a)) // [3, 4, 6, 5]
[...new Set(a)] // ES6 语法下的 Set 去重
笨办法:
// 使用双重循环,每次从原数组中提取一个数据和新数组中已有数据比较
13. 用正则表达式实现 string.trim()
function trim(string) {
return string.replace( /^\s+|\s+$/ ,'');
}
14. 原型?原型继承?Class 继承?
15. 有关 == 的问题(送命题)
例:( a==1 && a==2 && a==3 ) 可能为 true 吗?
答:可能。
例:null == undefined?
答:true
16. 手写一个 Promise(送命题)
// 谷歌一下
四. DOM 篇
1. DOM 事件模型是什么?
回答什么是冒泡和捕获即可。
2. 事件委托是什么?好处是什么?
答:不直接监听子元素,而是监听父元素,只需要在监听后判断是哪个“儿子”触发的事件。
好处:一次监听所有“儿子”,那怕是后面动态生成的“儿子”,也能被监听。
五. HTTP 篇
六. Vue2 篇
1. 生命周期
答:created(在实例创建完成后被立即调用)、mounted、updated 、destroyed(Vue 实例销毁后调用) 等生命周期钩子函数。
2. 组件间通信
答:父子通信(使用 Prop 传递数据、使用 v-on 绑定自定义事件),兄弟通信(new Vue() 作为 Bus 或者 Vuex),爷孙通信(可以 爷爷—>爸爸—>儿子 依次通信,也可以只用采用 Vuex 状态管理器等方案)
3. 数据响应式是什么原理
简单总结版:当把一个 JS 对象传入 Vue 实例作为 data 选项时,Vue 将遍历这个对象的所有属性,并使用 Object.defineProperty() 把这些属性全部转化为 getter/setter。这些 gettet/setter 对用户来说是不可见的,但是在内部它们让 Vue 可以追踪依赖,在属性被修改时通知变更。
4. computed 和 methods 和 watch 区别是什么?
计算属性 vs 方法:
- 两者不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。
- 每当触发重新渲染时,调用方法将总会再次执行函数。
计算属性 vs 侦听器
- 使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些是计算属性无法做到的。
5. Vue.set 是做什么用的?
答:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。如果采用普通的方法向对象中添加属性,那么这个新增属性不会是响应的。
6. Vuex 作用是什么?你会怎么用?
答:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
我如果开发一个博客,我会将用户"是否登录"这个状态放入到 Vuex 中,供所有组件访问和修改。
7. VueRouter 是什么?你会怎么用?
答:它是 vue.js 官方的路由管理器,它让我们构建单页面应用变得很简单。
我在做一个单页面应用,但想要实现多页效果的时候,我会把一个个页面对应为一个个的组件,然后用路由来管理它们,这样就实现了单页面应用。
七. 安全篇
1. 什么是 XSS?如何预防?
名称:跨站脚本攻击
举例:在一个论坛发帖中发布一段恶意的 JavaScript 代码完成脚本注入,如果这个代码内容有窃取用户数据并发送给外部服务器,那么就是一种 XSS!
预防:过滤尖括号、script 等特殊字符(把 < 替换成 <)、vue 中谨慎使用 v-html
2. 什么是 CSRF?如何预防?
名称:跨站请求伪造
举例:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。以此冒充用户发起请求(在用户不知情的情况下),完成一些违背用户意愿的请求(如恶意发帖,删帖,改密码,发邮件等)。
预防:添加验证码、进行 token 校验、同源策略、Samesite
八. 浏览器兼容篇
- 浏览器默认的 margin 和 padding 不同。解决方案:加一个全局的 *{margin:0;padding:0;} 来统一。
- 上下 margin 重合问题:IE 和 ff 都存在,相邻的两个 div 的 margin-left 和 margin-right 不会重合,但是 margin-top 和 margin-bottom 却会发生重合。