前端必会的知识点

BFC(Block Formatting Context)

  1. 渲染规则

    • 内部的子元素,在垂直方向,边距会发生重叠,但浮动(float)元素的区域则不会
    • 页面中它是独立的容器,外面的元素不会影响里面的元素
    • 计算其高度时,浮动的子元素也会参与计算
  2. 如何生成

    • 设置overflow:hidden
    • 设置浮动 float
    • 设置定位 position
    • 修改 display 属性为 inline-block,table-cell,table-caption,flex,inline-flex,实际前三种相当于变相写该 display 为 inline-block
  3. 应用

    • 解决 margin 塌陷(父子关系,实际也可以称为 margin 重叠),给子/父元素创建 BFC
    • 父元素没有高,而子元素浮动,创建 BFC,则相当于清除浮动,此时父元素会有高度,就是子元素高

浏览器的回流(reflow)与重绘(repaint)

浏览器使用的是流式布局模型,它会把HTML解析成DOM,CSS解析成CSSOM,然后合并成Render Tree,然后就可以根据这些信息,将节点绘制在页面上。值得注意的是Render Tree一般只需要遍历一次即可完成绘制,而table及其内部元素则需要多次计算,因此即可能避免使用table布局。

  1. 回流

    • 定义当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程

    • 触发条件

      • 页面首次渲染
      • 浏览器窗口大小改变
      • 元素尺寸或位置发生改变
      • 元素内容发生变化
      • 元素字体大小变化
      • 添加或删除可见的 dom 元素
      • 激活 css 伪类
      • 查询某些属性或调用某些方法
    • 一些常用且会导致回流的属性和方法
      clientWidth、clientHeight、clientTop、clientLeft
      offsetWidth、offsetHeight、offsetTop、offsetLeft
      scrollWidth、scrollHeight、scrollTop、scrollLeft
      scrollIntoView()、scrollIntoViewIfNeeded() getComputedStyle()
      getBoundingClientRect() scrollTo()

  2. 重绘

    • 定义当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility 等),浏览器重新绘制(渲染)的过程
  3. 如何避免

    • 尽可能不用 table 布局
    • 尽可能在 dom 树的最末端改变 class
    • 避免设置多重内联样式
    • 避免使用 css 表达式(eg:calc())
    • 避免频繁操作样式,最好一次性设置好
    • 避免频繁操作 dom,最好一次性插入文档中
    • 对复杂的动画元素使用绝对定位,避免对父元素及后续元素的影响
  4. 总结

    • 回流必将引起重绘,重绘不一定会引起回流

浏览器原理1
浏览器原理2

relative和absolute定位的区别

  1. relative
    元素会脱离正常的文档流,但其在文本流中的位置依然存在,其定位是相对于原本自身的位置,若没有设置宽度,则宽度为父元素的宽度,该元素的大小会影响父元素的大小。

  2. absolute
    元素会脱离文档流,但其在正常流中的位置不再存在,其定位是相对于离它最近的且不是static定位的父元素而言,若该元素没有设置宽度,则宽度由元素里面的内容决定,且宽度不会影响父元素。

原型链及闭包

原型链是面向对象的基础,主要包含的知识点有:

  1. 对象创建的方法

    • 字面量
    const o = { name: '小明' };
    const oo = new Object(name, '小明');
    
    • 构造函数
    function Person(name) {
      this.name = name;
    }
    const p = new Persion('小明');
    
    • Object.create
    const p = { name: '小明' };
    const o = Object.create(p);
    
    // {}
    console.log(o);
    // 小明
    console.log(o.name);
    

这种方法实际上是基于原型创建,p 是 o 的原型, o 则是实例,构造函数是 Object

  1. 原型,构造函数,实例之间的关系

    • 在访问一个实例的时候,如果实例本身没找到此方法或属性,就往原型上找。如果还是找不到,继续往上一级的原型上找。
  2. instanceof 的原理

    • 它的作用是判断实例是属于哪个构造函数
  3. new 运算符

    • 用于创建一个空对象实例
    • 执行构造函数,改变 this 指向,指向创建的实例
  4. 闭包(closure)

    • 定义
      能访问其他函数私有变量的函数
    function func1(){
        var f1 = 'haha';
        function f2(){
            // console.log(f1)
            return f1;
        }
        return f2;
    }
    这里的f2就是一个闭包
    
    • 闭包的特点
      读取函数内部变量,且这些变量常驻内存(垃圾回收机制无法自动回收)

    • 闭包的作用域链
      查找规则是指向顶层函数,实际是因为函数外面的变量保存在内部函数的词法作用域内,词法作用域的范围是由变量声明的位置决定。

闭包

面向对象

  1. 类的声明及实例化
function Person(name) {
  this.name = name;
}

// es6的写法,仅仅只是一种语法糖
class Person {
  constructor(name) {
    this.name = name;
  }
}

const p = new Person('小明');
  1. 继承

    • 借助构造函数
    function Animal(name) {
      this.name = name;
    }
    
    Animal.prototype.say = function() {
      console.log('cry');
    };
    
    function Dog(name, age) {
      Animal.call(this, name);
      this.age = age;
    }
    
    // Dog {name: "小黄", age: 6}
    const dog = new Dog('小黄', 6);
    

    注意: 此方法主要是让父类的属性添加到子类中来实现继承,实际就是改变 this 的指向,但是,父类的原型无法继承,也就是say无法获取

    • 原型继承
    function Animal(name) {
      this.name = name;
      this.info = {};
    }
    
    Animal.prototype.say = function() {
      console.log('cry');
    };
    
    function Dog(age) {
      this.age = age;
    }
    
    Dog.prototype = new Animal();
    
    const dog = new Dog(2);
    const old_dog = new Dog(10);
    
    dog.info.sex = 'male';
    
    // male
    console.log(old_dog.info.sex);
    

    注意:此方法会让多个子类共用父类的属性,只要实例有一个发生改变,其他的实例也会随着改变

    • 组合继承
    function Animal(name) {
      this.name = name || '';
      this.info = {};
    }
    
    Animal.prototype.say = function() {
      console.log('cry');
    };
    
    function Dog(age) {
      Animal.call(this);
      this.age = age;
    }
    
    Dog.prototype = new Animal();
    
    const dog = new Dog(2);
    const old_dog = new Dog(10);
    

注意: 此方法实际组合了上述两种方法的优点,但会执行父类构造方法两次

前端安全

  1. CSRF (Cross-site request forgery) 跨站请求伪造

    • 攻击原理
      用户小明登录 A 网站,并保留登录凭证(cookie),攻击者引诱小明访问 B 网站,B
      网站向 A 网站发送一个请求,A 网站接受到请求后,对请求进行验证,并确 认是小明
      凭证,误认为是小明自己发送的,然后 A 网站以小明的名义执行了攻 击者指定的操作,完成攻击

    • 防御方法

      • token 验证
        服务端给客户端发送一个 token,客户端提交表单或执行异步请求时带上该 token,然后服务端验证是否合法,若不合法则拒绝请求
    • 同源策略
      即 referer 验证,直接本站的请求,服务端才响应,如果不是则拒绝

  2. XSS (Cross Site Scripting) 跨站脚本攻击

    • 攻击原理
      其原理就是向页面(url,输入框)中注入可执行脚本

    • 防御方法

      • 对输入的数据进行编码
      • 过滤用户输入的属性和相关事件属性,如,script,iframe,style

http协议

  1. 三次握手

  2. 四次挥手

  3. 常用的状态码

204 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 部分内容(断点续传)
301 永久性重定向
302 临时性重定向
304 如果客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变
403 Forbidden (不允许访问 )
500 Internal Server Error/内部服务器错误
503 Service Unavailable
  1. http和https的区别

http传输的数据是未加密,明文的,而https传输的是加密数据。
简言之,https=ssl/tsl+http

  1. 缓存
  • 强缓存
    它是指不用请求服务器,直接使用本地缓存,是利用 http 响应头中
    ExpiresCache-control实现的,且后者的优先级更高。Expires是服务器返回的绝对时间,当服务端和客户端时间相差较大时,就可能影响缓存的结果,而Cahce-control返回的是相对时间,超出相对时间则,进行更新。

  • 协商缓存
    它返回的状态码是304,它是利用 http 响应头中的Last-ModifiedIf-Modified-SinnceEtagIf-None-Match

http协议
http缓存
https加密过程

  1. 设置响应消息头Access-Control-Allow-Credentials值为“true”
  2. 设置响应消息头Access-Control-Allow-Origin值为指定单一域名(注:不能为通配符“*”)
  3. 客户端需要设置Ajax请求属性withCredentials=true,让Ajax请求都带上Cookie
    eg: axios.defaults.withCredentials=true; // 让ajax携带cookie

白屏及首屏时间计算

  1. 白屏
    白屏是指浏览器开始显示内容所花费的时间。一般我们以浏览器开始渲染 body 标签或者解析完 head 标签的时刻就是页面白屏结束的时间点。
...
<head>
  <meta charset="UTF-8">
  <title>白屏</title>
  <script type="text/javascript">
    window.firstPaint = Date.now();
  </script>
</head>
<body>
  <!-- 页面内容 -->
</body>
...

白屏时间 = firstPaint - performance.timing.navigationStart

  1. 首屏
    首屏指用户打开网站开始,到浏览器首屏内容渲染完成的时间。一般以一个指定dom加载完成时间来计算首屏时间即首屏时间 = 指定dom加载完成时间 - performance.timing.navigationStart

另外,performance.getEntriesByType('navigation'),
performance.getEntriesByType('resource')可以来监测性能

内存泄漏

内存泄漏