【自种树自乘凉】前端高频知识点 - 面向面试复习法

1,083 阅读9分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

是时候寄出失传已久的——面向面试复习法!

目录:

  1. HTML篇
  2. CSS篇
  3. JS篇
  4. DOM篇
  5. HTTP篇
  6. Vue2篇
  7. 安全篇
  8. 浏览器兼容篇

一. 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;

垂直居中:

CSS 实现垂直水平居中

3. Flex 怎么用?常见的属性有哪些?

Flexbox 弹性布局总结

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):

  1. 选择器越具体(权重之和越大)优先级越高
  2. 写在后面的 CSS 覆盖前面的 CSS
  3. !important 优先级最高,但是建议少用。

6. 清除浮动的代码?

父元素添加如下代码,里面的子元素就清除浮动了:

.clearfix::after {
  content: ""; // 空串
  display: block; // 显示为块级元素
  clear: both; // 清除两侧浮动的影响
}

.clearfix {
     zoom: 1; // IE兼容
 }

或者直接:overflow: hidden; 但不建议用这个。

三. JS 篇

1. ES6 语法知道哪些?怎么用?

ES6 新特征总结

2. Promise 分别怎么用?

Promise 的用法之 then 的用法:

$.ajax(...).then(成功函数, 失败函数)

链式 then 的用法:

$.ajax(...).then(成功函数1, 失败函数1).then(成功函数2, 失败函数2)

其他方法,例如 Promise.all、Promise.race,建议直接通读:

ES6 标准入门 - Promise 篇 - 阮一峰

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

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 继承?

初识JS原型/原型链/原型继承

15. 有关 == 的问题(送命题)

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

答:可能。

例:null == undefined?

答:true

16. 手写一个 Promise(送命题)

// 谷歌一下

四. DOM 篇

1. DOM 事件模型是什么?

回答什么是冒泡和捕获即可。

2. 事件委托是什么?好处是什么?

答:不直接监听子元素,而是监听父元素,只需要在监听后判断是哪个“儿子”触发的事件。

好处:一次监听所有“儿子”,那怕是后面动态生成的“儿子”,也能被监听。

五. HTTP 篇

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 等特殊字符(把 < 替换成 &lt;)、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 却会发生重合。