Logic

Logic 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

Think Young, Do Simple.

个人动态

Logic 发布了文章 · 2月1日

前端面试题整理【入门版】

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

image.png

  • js基础技术

    • VUE

      • vue2

        • 双向绑定原理

          • get时collect,set时notify
          • v-model原理,监听input输入框的input事件

            • 如果直接document.querySelector('xxx input').value = new value,v-model对应的值会变化么,为什么
          • input与change区别
          • computed与watch区别
          • this.$set与Vue.set区别
        • vue实例与父子组件

          • vue组件内写的this指向谁
          • 计算属性,函数名和data数据源中的数据可以同名吗,为什么
          • 给vue定义全局的方法
          • 父子组件生命周期是如何串起来的
          • 组件通信方案
          • project/reject的理解,使用时需要每一个组件内都注入么
          • EventBus注册在全局上时,路由切换时会重复触发事件,如何解决呢
          • 父子组件如何访问彼此的实例
        • 其他问题

          • vue2.0不再支持v-html中使用过滤器了怎么办
          • 函数式组件特点与应用场景
          • vue为什么要求组件模板只能有一个根元素
          • :class和:style有几种表示方式
          • nextTick的原理
          • spa的seo怎么做

            • ssr的渲染时机示什么
        • v-for的key绑不绑定有什么区别

          • 原地复用机制
          • 子级依赖索引问题
        • vue router的原理

          • keep alive原理
          • router link原理
          • 页面加载完成后,非当前路由的部分开始了生命周期么
        • vue-cli

          • 在使用vue-cli开发vue项目时,自动刷新页面的原理你了解吗
          • vue-cli怎么解决跨域的问题,是什么原理
        • diff算法

          • react与vue的区别、传统diff的局限、vdom如何提高性能
          • vue3为啥更快
      • vue3

        • proxy-reflect优化的原因
        • 对象的子级对象的双向绑定,vue是如何处理的
        • composition API优点
        • 其他优化
    • webpack

      • vue文件是如何变成js文件的,有哪些环节

        • webpack build与vue-cli dev场景分别有什么区别
      • webpack打包的流程、loader、plugin区别、polly-fill原理
      • hash、content-hash、chunk-hash区别
      • tree-shaking原理

        • 模块规范的区别
        • 如何写一个兼容amd cmd的模块
    • http

      • get post区别 安全 / 幂等
      • 版本演进

        • tcp-ip握手与ssl握手

          • 知道ssl是非对称+对称加密
      • 常见端口号 204 206 302 304 403 503
      • 并发问题

        • 支持多少tcp/ip并发
        • 每一个tcp-ip可以发送多个http么
      • 缓存策略

        • 缓存优先级
        • 强缓存

          • 知道pragma有加分但不要求
        • 协商缓存

          • 两种方案区别与各自的问题以及如何处理的
          • 同时使用两种协商缓存策略,如何处理的
          • no-cache与no-store区别
        • 200 from memory cache 与 200 from disk cache区别
        • 之前项目的缓存策略
      • 跨域问题

        • 原因与表现
        • 问题:server资源 / localstorage资源
        • 解决方案

          • cros可以配置什么内容
          • postMessageAPI如何使用
          • JSONP运行流程与限制
          • nginx配置代理转发
          • coop coep等【不硬性要求】
    • 原型链

      • 如何获取一个对象的原型对象有哪些方案
      • 为何不建议使用__proto__,以及应该怎么实现这种场景的需求
      • 1.__proto__和a = 1; a.__proto__有什么区别

        • 拆箱与装箱
        • primitive (primitive value, primitive data type)是什么
        • primitive 可更改值么
      • 通过原型链实现继承有哪些方案

        • 注:prototype指向过去,一定要constructor指向回来才算
    • eventLoop

      • setTimeout(fun, 0), fun是什么时机触发的,属于第一次事件循环序列的宏任务还是第二次的,第二次序列里面的宏任务最前还是最后
      • 渲染是何时进行的
      • setInterval的执行策略与setTimeout有什么区别
      • 栈与队列的概念

        • 可以顺带聊一下 尾递归优化 不强求
    • 安全策略

      • xss三种原理与防范
      • xsrf原理与防范
    • 其他

      • promise

        • all 如何容错式返回
        • 手写一个all / race
      • es6

        • weak map与map
        • let const的理解
      • this

        • 函数指向
        • 闭包指向
        • class内function的指向
        • bind之后还可以改变this指向么
      • 闭包
      • 柯里化

        • 说得清楚如何实现即可,不强制要求
      • 高阶函数

        • 主要考察理念的理解和arr的一些方法,其他更深层次的概念不做强制要求
      • 手写bind
      • iife
  • css等

    • 居中方案
    • 圣杯、双飞燕
    • animation参数
    • flex、grid相关与兼容处理
    • 动效优化、transition与animation渲染的区别
    • 补间动画
    • fps与raf概念
    • 盒模型与互相转化
    • 清除浮动
  • 浏览器

    • arr的sort默认算法是什么
    • url到页面加载出来的流程
    • ast如何构建、ast有哪些属性【不要求】
    • 词法分析、语法分析区别
    • 常见的兼容问题
    • 屏幕适配问题
    • 存储策略

      • localstorage、cookies、ss、IndexDB等区别与各自空间大小、空间大小、url长度限制 等
    • 写一个10px为何调试的时候会是10.222px或者8.666px
    • 沙箱、webworker原理与应用空间与限制
  • 团队建设与优化

    • 错误收集与报警 https://segmentfault.com/a/1190000016959011

    • 性能优化

      • 资源型

        • 应体积越小越好, 尽可能复用传输通道,利用缓存
        • 优化显示关键资源, 优先加载头部内容, 用户主观感受更快
      • 渲染型

        • 尽量局部重排、集中式操作、分离读写操作、dom离线、脱离文档流
    • ci/cd

      • 如何集成到项目里,遇到管理性质的流程如何处理
    • 公共组件维护

      • git submodule、git subtree、npm 以上方案的优缺点以及如何使用与优化的
    • 效率提升

      • cli优化
      • 流程优化
  • 算法

    • 数组查重,至少三个

      • set ,obj-key,arr的index reduce find等方法,
    • 深拷贝

      • JSON的缺陷
      • 循环引用的处理
      • weakmap 与while优化
      • 正则,函数 箭头函数,eval等情况的处理
    • 实现节流 防抖
    • 实现lodash里面某一个算法,比如chunk
    • 链表查环
    • 斐波那契
    • 深度优先遍历与广度优先遍历
    • 如何写一个加减法的编译器
    • 基本思路理解:递归、贪心、动态规划、回溯、时空复杂度的计算
  • 业务问题

    • h5

      • 1px像素问题
      • 适配处理问题 / 原理
      • 滚动穿透
      • ios300ms延迟
      • 上传的问题

        • 低版本Android上传图片回来刷新的问题 、无权限如何处理 、 如何打开相册
      • 音乐

        • 自动播放 、 如何预加载
      • 视频上层覆盖按钮
    • pc

      • 主流浏览器兼容
      • sso方案
      • 如何避免运营商劫持
      • 数据可视化相关方案
      • 响应式设计方案
      • 权限管理方案
      • 截留 / 防抖
      • 登录态管理
      • 万级节点优化
  • 其他

    • 跨平台

      • 主流框架与方案
      • 各个方案的原理
    • 前端未来方向的思考

      • BFF、TWA 方向;UI 智能化方向;数据可视化方向;图形互动化方向;serveless、可视化、动效、3d+vr+ar、第三方扩展能力、等
    • node 常用api等
    • eslint、babel等的原理
【By: 360手机助手团队-XTeam】
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 2 收藏 2 评论 0

Logic 发布了文章 · 2月1日

前端面试题整理【基础版】

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

image.png

  • js基础技术

    • VUE

      • vue2

        • 双向绑定原理

          • get时collect,set时notify
          • v-model原理,监听input输入框的input事件

            • 如果直接document.querySelector('xxx input').value = new value,v-model对应的值会变化么,为什么
          • input与change区别
          • computed与watch区别
          • this.$set与Vue.set区别
        • vue实例与父子组件

          • vue组件内写的this指向谁
          • 计算属性,函数名和data数据源中的数据可以同名吗,为什么
          • 给vue定义全局的方法
          • 父子组件生命周期是如何串起来的
          • 组件通信方案
          • project/reject的理解,使用时需要每一个组件内都注入么
          • EventBus注册在全局上时,路由切换时会重复触发事件,如何解决呢
          • 父子组件如何访问彼此的实例
        • 其他问题

          • vue2.0不再支持v-html中使用过滤器了怎么办
          • 函数式组件特点与应用场景
          • vue为什么要求组件模板只能有一个根元素
          • :class和:style有几种表示方式
          • nextTick的原理
        • vue router的原理

          • keep alive原理
          • router link原理
          • 页面加载完成后,非当前路由的部分开始了生命周期么
        • vue-cli

          • vue-cli怎么解决跨域的问题,是什么原理
        • diff算法

      • vue3

        • proxy-reflect优化的原因
        • 对象的子级对象的双向绑定,vue是如何处理的
        • composition API优点
        • 其他优化
    • webpack

      • vue文件是如何变成js文件的,有哪些环节

        • webpack build与vue-cli dev场景分别有什么区别
      • hash、content-hash、chunk-hash区别
      • tree-shaking原理

        • 模块规范的区别
        • 如何写一个兼容amd cmd的模块
    • http

      • get post区别 安全 / 幂等
      • 版本演进

        • tcp-ip握手与ssl握手

          • 知道ssl是非对称+对称加密
      • 常见端口号 204 206 302 304 403 503
      • 并发问题

        • 支持多少tcp/ip并发
        • 每一个tcp-ip可以发送多个http么
      • 缓存策略

        • 缓存优先级
        • 强缓存

          • 知道pragma有加分但不要求
        • 协商缓存

          • 两种方案区别与各自的问题以及如何处理的
        • 200 from memory cache 与 200 from disk cache区别
        • 之前项目的缓存策略
      • 跨域问题

        • 原因与表现
        • 问题:server资源 / localstorage资源
        • 解决方案

          • cros可以配置什么内容
          • postMessageAPI如何使用
          • JSONP运行流程与限制
          • nginx配置代理转发
    • 原型链

      • 如何获取一个对象的原型对象有哪些方案
      • 为何不建议使用__proto__,以及应该怎么实现这种场景的需求

      • 通过原型链实现继承有哪些方案

        • 注:prototype指向过去,一定要constructor指向回来才算
    • eventLoop

      • setInterval的执行策略与setTimeout有什么区别
      • 栈与队列的概念

        • 可以顺带聊一下 尾递归优化 不强求
    • 安全策略

      • xss三种,原理与防范
      • xsrf原理与防范
    • 其他

      • promise

        • all 如何容错式返回

        • 手写一个all / race

      • es6

        • weak map与map

        • let const的理解

      • this

        • 函数指向

        • 闭包指向

        • class内function的指向
      • 闭包
      • 柯里化

        • 说得清楚如何实现即可,不强制要求

      • 高阶函数

        • 主要考察理念的理解和arr的一些方法,其他更深层次的概念不做强制要求

      • 手写bind
      • iife
  • css等

    • 居中方案
    • 圣杯、双飞燕
    • animation参数
    • 补间动画
    • fps与raf概念
    • 盒模型与互相转化
    • 清除浮动
  • 浏览器

    • url到页面加载出来的流程
    • 常见的兼容问题
    • 屏幕适配问题
    • 存储策略

    • 性能优化

      • 资源型

        • 应体积越小越好, 尽可能复用传输通道,利用缓存
        • 优化显示关键资源, 优先加载头部内容, 用户主观感受更快
      • 渲染型

        • 尽量局部重排、集中式操作、分离读写操作、dom离线、脱离文档流
  • 算法

    • 数组查重,至少三个

      • set ,obj-key,arr的index reduce find等方法,
    • 深拷贝

      • JSON方案的缺陷
    • 实现节流 防抖
    • 实现lodash里面某一个算法,比如chunk
    • 链表查环
    • 斐波那契
    • 深度优先遍历与广度优先遍历

*   基本思路理解:递归、贪心、动态规划、回溯、时空复杂度的计算
    
  • 业务问题

    • h5

      • 1px像素问题
      • 适配处理问题 / 原理
      • 滚动穿透
      • ios300ms延迟
      • 上传的问题

        • 低版本Android上传图片回来刷新的问题 、无权限如何处理 、 如何打开相册
      • 音乐

        • 自动播放 、 如何预加载
      • 视频上层覆盖按钮
    • pc

      • 主流浏览器兼容
      • sso方案
      • 如何避免运营商劫持
      • 数据可视化相关方案
      • 响应式设计方案
      • 权限管理方案
      • 截留 / 防抖
      • 登录态管理
      • 万级节点优化
  • 其他

    • 跨平台

      • 主流框架与方案
    • 前端未来方向的思考

      • BFF、TWA 方向;UI 智能化方向;数据可视化方向;图形互动化方向;serveless、可视化、动效、3d+vr+ar、第三方扩展能力、等
    • node 常用api等
    • eslint、babel等的配置
【By: 360手机助手团队-XTeam】
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 0 收藏 0 评论 0

Logic 发布了文章 · 2020-12-23

浏览器原理--编译流程初探

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

Browser Introduction

浏览器基础架构
image.png
浏览器主要组成部分
image.png
渲染引擎的基本工作流
image.png

Parsing & DOM tree construction

解析流程
image.png
编译流程
image.png

DEMO

2 + 3 - 1


词法分析:
这个语言可以包含整数、加号和减号。


语法分析:
语法构建块是表达式、术语、操作。
这个语言可包含任何数量的表达式。
一个表达式被定义为:一个术语后面跟着一个操作,操作后面跟着另一个术语。
一个操作就是一个加号或一个减号
一个术语是一个整数或一个表达式。

HTML解析遵循的原则:

W3C: HTML 的词汇和语法规则
DTD: Document Type Definition 文档类型声明
软语法 !== XML XHTML

DOM Document Object Model
我们看一个例子
image.png
被解析为
image.png

解析算法流
image.png

语言的宽容特性:浏览器容错,以支持众所周知的无效 HTML 案例。解析过程是可重入的(reentrant)。document.write

标记算法
image.png
image.png

DOM树构造算法
image.png
image.png
当解析器创建好时,Document 对象也创建好了

在树的构建阶段,会改变包含 Document 根节点的 DOM 树,还会添加元素到 DOM 树。每个被分词器释放的节点都将被树构建器加工

对于每个标记,规范会定义与它相对应的 DOM 元素,并且为该元素创建这个 DOM 元素

除了将元素添加到 DOM 树中外,还会将元素添加到一个开放元素的堆中。这个堆用于修正嵌套错误和未关闭的元素。

构建算法是通过状态机的形式表示的。这些状态叫作"嵌入模式"。

解析结束的操作

浏览器会标记文档是可交互的,然后开始解析"延迟"模式(deferred mode)下的脚本——在文档解析完成后执行。此时,文档状态变成 "完成",抛出一个 "load" 事件。

浏览器容错

在 HTML 页面上,永远不会出现 "无效语法"(Invalid Syntax)的错误。浏览器会修正它,然后继续运行。
浏览器容错机制

image.png
image.png
image.png
image.png
image.png
image.png
image.png

CSS解析器

image.png

解析JS

网络模型是同步的【同步 async defer】
预解析
image.png

当有样式在加载和解析时,Firefox 会阻塞所有的脚本。
Webkit 仅会阻塞这些试图获取特定的样式属性,这些属性可能会受未加载的样式影响,的脚本。

Render tree construction

渲染引擎的基本工作流
image.png
webkit主流程
image.png
Gecko主流程
image.png
渲染树 由可视元素组成,

        这些元素按将要展示的顺序排列。
        它是文档的视觉呈现。
        渲染树的目的是保证内容有序绘制。

一个渲染器知道如何布局和绘制自身及其子类。

Firefox 把渲染树中的元素叫作 "帧"(frames)。

Webkit 把这些元素叫作 "渲染器"(renderer)或 "渲染对象"(render object)。

webkit盒模型

image.png

Render树的构建
1 渲染器与 DOM 元素相对应,但并不是一对一的关系。非可视元素不会被插入到渲染树,比如 head 元素。display !== visibility
2 有些 DOM 元素会对应多个可视对象。有些元素结构比较复杂,所以不能用单个矩形来表示。比如,select 元素有3个渲染器
3 当文本在一行内显示不下,被拆分成多行时,新行中的文本会被添加到新的渲染器中。
4 如果行内元素既包含了行内元素又包含了块级元素,会创建一个匿名块级渲染器包裹这些行内元素。
5 有些渲染对象与 DOM 节点一对一对应,但是在树中的位置却不同。浮动和绝对定位的元素脱离了流,放置在树的不同位置,然后映射到实际的帧。它们存在于占位符帧中。

渲染树和与之对应的 DOM 树,Viewport 是初始的包含块。
在 Webkit中,Viewport 是 RenderView 对象。
image.png
Webkit 中,分解样式和创建渲染器的过程叫作 "附着"(attachment)。每个 DOM 节点都有一个 attach 方法。"附着" 是同步的,节点插入到 DOM 树中会调用新节点的 attach 方法。
Firefox 中,构建过程表现为为 DOM 的更新注册一个监听器(listener),然后将帧的创建委派给 “帧构建器”,构建器会分解样式,创建帧。

样式计算

构建渲染树需要计算每个渲染对象的可视属性。通过计算每个元素的样式属性来完成

样式计算带来了一些难题

1、样式数据的结构庞大,包含了许多的样式属性,可能会引起内存问题。
2、如果没有优化,那么为每个元素查找匹配规则会导致性能问题。为每个元素查找匹配遍历整个规则表是一项繁重的任务。

  选择器可以有复杂的结构,这会导致匹配过程会从看上去有希望的路径开始匹配,而实际上却是无效的,然后再去尝试新的匹配路径。

3、应用规则涉及非常复杂的级联规则,这些规则定义了规则的层次结构。

共享样式数据(Sharing style data)

Webkit 节点引用样式对象(渲染样式 RenderStyle)。这些对象在某些情况下,可以被节点共享。这些节点是兄弟节点以及:

1、这些元素必须在相同的鼠标状态下(比如,不能一个是 :hover 状态,其他的不是)
2、元素不应该有 ID
3、标签名称应该能匹配
4、class 属性应该能匹配
5、映射属性集必须完全相同
6、link 状态必须匹配
7、focus 状态必须匹配
8、元素不能受到属性选择器的影响,影响被定义为可匹配到使用了元素中的任何属性的属性选择器。
9、元素不能存在行内样式属性
10、不能使用兄弟选择器。WebCore 遇到兄弟选择器时会抛出一个全局开关,为整个文档关闭样式共享。这些选择器包括:+ 选择器,:first-child 和 :last-child 等。

Firefox 规则树(Firefox rule tree)
为了更简单的样式计算,Firefox 提供了两种树

规则树和样式上下文树。
image.png

Webkit 也有样式对象,但是他们不是储存在类似于样式上下文树的树中,它只有 DOM 节点指向相应的样式。
渐进的过程:
Webkit 使用一个标志来标记顶层样式表是否加载完成(包括 @imports)。
当使用样式时,发现样式没有完全加载完成,将会使用占位符,并且在文档中进行标记,当样式加载完成时,会重新进行计算。

Layout & Painting

Layout

渲染器创建完成并被添加到渲染树时,它没有位置(position)和 大小(size)。

计算这些值的过程叫作 布局(layout)和 回流(reflow)

HTML 使用基于流的布局模型,从左到右、从上到下。
但也有例外——比如 tables,就需要多次计算(3.5)

坐标系统和根框架相关,使用上侧和左侧坐标。

布局是一个递归的过程。从根渲染器开始,与 HTML 文档的元素相对应。布局会在其中一些或所有框架层级中持续递归,为每个渲染器计算几何信息。

根渲染器的位置是 0,0,它的大小是视口大小——浏览器窗口的可视部分。

所有的渲染器都有一个 layout(布局) 和 reflow(回流) 方法,每个渲染器都会调用那些需要布局的子渲染器的 layout 方法。

脏值系统

为了避免为每个小的变动都进行一次完整的布局,浏览器使用了脏值系统。

一个渲染器改变或添加了之后会标记自己及其子代为“dirty”——需要布局。

有两种标志——“dirty”和“children are dirty”。后者意味着虽然渲染器本身没问题,但是它至少有一个需要布局的子代。

布局过程

布局通常有下面几种模式:

父渲染器决定自己的宽度
父渲染器遍历子渲染器,然后
放置子渲染器(设置它的x和y)
如有需要,调用子渲染器的layout(布局)方法——它们是脏的或者我们在全局布局中,或者其他某些原因——这会计算子渲染器的高度。
父渲染器使用子渲染器的高度、外边距、内边距的累加高度来设置自己的高度——父渲染器的父渲染器也会使用这个高度。
设置脏值为false。

在一个渲染器在布局过程中发现需要折行,它会停下来,通知父渲染器它需要折行。父渲染器就会创建额外的渲染器,然后调用这些渲染器的layout方法。

Painting

在绘制阶段,会遍历渲染器树,调用渲染器的 paint 方法,在屏幕上排列内容。绘制使用 UI 基础组件
CSS2 规定了绘制程序的顺序。这实际上就是元素在层叠上下文(stacking context)中如何层叠的顺序。

一个块级渲染器的层叠顺序如下:

background color(背景颜色)
background image(背景图片)
border(边)
children(子级)
outline(轮廓)

【By: 360手机助手团队-XTeam】
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 1 收藏 1 评论 0

Logic 发布了文章 · 2020-12-23

2020前端知识图谱

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

image.png

  • js框架

    • vue

      • 双向绑定
      • diff算法
      • vDom
    • react

      • fibber
      • RN
      • redux
    • angular

      • 脏检查机制
    • Type Script

      • 装饰器
      • 强类型
  • 原生技术

  • 工程化

    • 模块

      • amd / umd / cmd / ES Moudule
    • 规范

      • eslint
    • 打包流程

      • 基本流程
      • loaders
      • plugins
      • hash缓存策略
      • tree-shaking
    • 自动化

      • 自动构建
      • CI / CD
  • 经典范式与理念的使用

    • Currying(柯里化)
    • point-free 函数
    • partial function 应用
    • 高阶函数 函数式编程
    • 纯函数
    • 副作用
    • 闭包
  • 监控

    • 行为分析

      • 定制化收集【核心kpi收集】与自动化收集【核心kpi收集、用户操作行为分析】
    • 错误分析

      • window.onError, unRejectHandler,Vue.onError,console.Error, throw, catch, netWrok-404等
    • 性能分析

      • 性能监测

        • 收集指标
        • 评估方式
      • 性能调优

        • ssr
        • 数据收集
        • 包管理
        • tree-shaking
        • 考虑5G大流量下的极致性能优化体验
      • WebAssembly asm
  • 安全

    • 数据加解密

      • rsa
      • md5
    • 网页签名
    • 反作弊,客户端加盐
    • 如何做到安全的数据共享

      • 单点登录
      • 扫码登陆
    • csrf
    • xss

      • dom
      • 反射
      • 存储
    • xs-leaks
  • 经典业务问题

    • 1px像素兼容
    • 双飞燕 / 圣杯布局
    • 居中问题
    • 适配问题
    • pc-权限管理实现方案
    • 跨域问题
    • 弹窗滚动穿透问题
  • 跨平台技术 https://segmentfault.com/a/1190000022106809

    • hybrid
    • RN
    • taro
    • flutter
    • Electron
    • Cordova / 快应用 等
  • ui框架

    • element
    • iview
    • vuetify
    • cube-ui
    • vue-beauty
    • ant
  • html方言

    • slim等
  • 状态通讯与数据模型

    • vuex
    • redux
    • Mobx
  • 兼容性

    • h5

      • android
      • ios
    • pc

      • chrome
      • ie 8 / 11
      • fire fox
      • safari
  • scence(工具与常见坑)

    • 小程序

      • mina / mpvue / tina / wepy
    • 小游戏

      • cocos / unity / lua / three.js / h52小游戏等
    • h5小游戏

  • 交互中间件

    • 通讯协议
    • 数据mock
    • 跨域与请求方法类型模拟
  • 工作流

    • 项目初始化
    • 成长包管理

      • 一些自己写的工具库,或者抽离出来的辅助函数,如何做到自动化维护
    • 部署发布(一套完整的上线管理流程)
  • 测试

    • 前端自动化测试
    • 边界与单元测试
  • css编写规范与逻辑css

    • BEM、OOCSS、SMACSS
    • less
    • sass
  • 服务端开发

    • node js
    • sql / mongDB等
    • 并发、协议、缓存、文件等
  • 第三方服务

    • 地图、统计图表与数据分析侧的常用模式

      • echart、d3、threeJs、high-charts
    • 音视频剪辑

      • 声纹识别、同传翻译等科大讯飞系的web接口
    • 大数据与AI侧的web接口

      • python-动态生成网页等
      • 百度 / 高德地图系的web接口
    • 图片合成、剪辑与滤镜等

      • face-plus / 天天p图系的web接口
  • 现代浏览器技术及前端系的各种玩法

    • canvas技术的深度使用
    • css3与设计的深度使用
    • 新语法糖的使用与带来的开发效率提升
  • 架构设计思想

    • 遵循原则

      • 单一原则
    • 设计模式

      • 单例模式
      • 工厂模式
      • 代理模式
      • 观察者模式
      • 订阅发布模式
      • 职责链模式等
  • 大方向--https://juejin.cn/post/6844903652470046734玉伯

    • 无感化, TWA 是 Techless Web App 的缩写
    • BFF与serveLess
    • UI 智能化方向
    • 数据可视化方向
    • 图形互动化方向
【By: 360手机助手团队-XTeam】
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 2 收藏 1 评论 1

Logic 发布了文章 · 2020-12-23

吐血整理:http常用基础知识

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

谈起http协议,大家第一印象一般都会直接想到tcp-ip + ssl/tls 握手过程。今天从另一个角度为大家梳理一下http相关的一些知识点。

本文主要有7个方面,分别是

1、http演进历史,会大致介绍一下每个版本的更新内容、遇到的问题与当时的改进方案
2、http缓存策略
3、跨域策略
4、http的并发问题
5、get/post区别与常见端口号
6、一些开放性的问题
7、最后把本文成文过程中参考的各位巨人的肩膀给罗列出来。

一、HTTP的演进

1、http 0.9

  • 只允许客户端发送GET这一种请求,且不支持请求头
  • 只支持一种内容,即纯文本,支持html但 无法插入图片

2、http 1.0

  • 请求与响应支持头域
  • 响应对象以一个响应状态行开始
  • 响应对象不只限于超文本
  • 开始支持客户端通过POST方法向Web服务器提交数据,支持GET、HEAD、POST方法
  • 支持长连接(但默认还是使用短连接),缓存机制,以及身份认证

3、http 1.1

新特性:
  • 默认为长连接
HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection:keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
  • 提供了范围请求功能(宽带优化)
HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。这是支持文件断点续传的基础。
  • 提供了虚拟主机的功能(HOST域)
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
  • 多了一些缓存处理字段
HTTP/1.1在1.0的基础上加入了一些cache的新特性,引入了实体标签,一般被称为e-tags,新增更为强大的Cache-Control头。
  • 错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
问题:
  • 高延迟 — 队头阻塞(Head-Of-Line Blocking)
  • 无状态特性 — 阻碍交互
    协议对于连接状态没有记忆能力,服务器并不知道它与上一条请求有何关联,换句话说就是掉登录态
  • 明文传输 — 不安全性
    传输内容没有加密,中途可能被篡改和劫持。
改进方案:
  • 针对队头阻塞:
1.将同一页面的资源分散到不同域名下,提升连接上限。虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。
2.减少请求数量
3.内联一些资源:css、base64 图片等
4.合并小文件减少资源数
  • 针对不安全性:
1.https
2.token验签
3.定制化/约定:数据加密方案

4、http 2

新特性:
  • 二进制分帧传输:
1) HTTP 2.0 的所有帧都采用二进制编码
2) 帧是最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。多路复用,就是在一个 TCP 连接中可以存在多个流
3) 帧:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。
4) 消息:是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。
5) 流:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1、2 … N);
  • 多路复用 — 解决队头阻塞
多路复用允许同时通过单一的HTTP/2.0 连接发起多重的请求-响应消息。有了新的分帧机制后,HTTP/2.0不再依赖多个TCP 连接去处理更多并发的请求。每个数据流都拆分成很多互不依赖的帧,而这些帧可以交错(乱序发送),还可以分优先级。最后再在另一端根据每个帧首部的流标识符把它们重新组合起来。HTTP 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个域名一个连接)即可。
  • 头部压缩 — 解决巨大的 HTTP 头部
HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。HTTP/2.0 要求通讯双方各自缓存一份首部字段表,从而避免了重复传输。
  • 请求优先级 — 先获取重要数据
浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不必排队了,既节省了时间,也最大限度地利用了每个连接。
  • 服务端推送 — 填补空缺,提高请求效率
请求 index.html 可以把首次依赖的js、css直接返回,方法是在nginx上配置一下就行
  • 提高安全性
基于https
问题:
  • TCP 以及 TCP+TLS 建立连接的延时:TCP 连接需要和服务器进行三次握手,即消耗完 1.5 个 RTT(Round-Trip Time,往返时延)
  • TCP 的队头阻塞并没有彻底解决:

    • TCP 为了保证可靠传输,有一个“超时重传”机制,丢失的包必须等待重传确认。
    • HTTP2 出现丢包时,整个 TCP 都要等待重传,那么就会阻塞该 TCP 连接中的所有请求。
  • 多路复用导致服务器压力上升
  • 多路复用容易 Timeout

5、http 3【Google基于 UDP 协议的 QUIC 协议】

新特性:
  • 改进的拥塞控制、可靠传输
  • 快速握手
  • 集成了 TLS 1.3 加密
  • 多路复用
  • 连接迁移
问题:

NAT

在一些 NAT 网络环境下(如某些校园网),UDP 协议会被路由器等中间网络设备禁止,这时客户端会直接降级,选择 HTTPS 等备选通道,保证正常业务请求。

二、 缓存

1、缓存类型

  • 200 form memory cache :不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
  • 200 from disk cache:不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
  • 优先访问memory cache,其次是disk cache,最后是请求网络资源

2、强/协商缓存

1)强缓存 expires / cache-control: max-age=600

  • Expires:过期时间,如果设置了时间,则浏览器会在设置的时间内直接读取缓存,不再请求
  • Cache-Control:当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。

    • private无表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)public可省略表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存no-cache可省略缓存前必需确认其有效性no-store无不缓存请求或响应的任何内容max-age=[s]必需响应的最大值
    • (1) max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;
    • (2) s-maxage:和max-age是一样的,不过它只针对代理服务器缓存而言;
    • (3)public:可省略 指示响应可被任何缓存区缓存;响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存
    • (4)private:无参数,只能针对个人用户,而不能被代理服务器缓存;
    • (5)no-cache:可省略 强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到 请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。这个很容易让人产生误解,使人误以为是响应不被缓存。实际上Cache-Control: no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。
    • (6)no-store:无参数,禁止一切缓存(这个才是响应不被缓存的意思)。

2)协商缓存

  • last-modify + if-modify-since http1.0

    • Last-Modified:浏览器向服务器发送资源最后的修改时间
    • If-Modified-Since:
    • 当资源过期时(浏览器判断Cache-Control标识的max-age过期),发现响应头具有Last-Modified声明,则再次向服务器请求时带上头if-modified-since,表示请求时间。服务器收到请求后发现有if-modified-since则与被请求资源的最后修改时间进行对比(Last-Modified),若最后修改时间较新(大),说明资源又被改过,则返回最新资源,HTTP 200 OK;若最后修改时间较旧(小),说明资源无新修改,响应HTTP 304 走缓存。
  • ETag + if-not-match HTTP 1.1

    • Etag是属于HTTP 1.1属性,它是由服务器(Apache或者其他工具)生成返回给前端,用来帮助服务器控制Web端的缓存验证。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
    • if-not-match 当资源过期时,浏览器发现响应头里有Etag,则再次像服务器请求时带上请求头if-none-match(值是Etag的值)。服务器收到请求进行比对,决定返回200或304

3)不缓存 Pragma: no-cache / catch-control: no-store
4)缓存优先级

  • 顺序的话是先判断http1.0 的【Pragma: no-cache】再, Cache-Control 再Expires,再【 ETag,最后 Last-Modified,都满足就 304,有一项不满足就 200。】
  • 强缓存

    • expires更多是为了支持http/1.0的上古浏览器的响应头,是一个具体的时间点,可能客户端与服务器时间不一致,或者网络延迟导致时间不准确
    • cache-control: max-age是一个秒数,两者同时出现以max-age为准
  • 协商缓存

    • 一般分布式环境下(比如 CDN)很少使用ETag,因为ETag依赖 Web Server 的哈希算法,不同 Web Server、不同版本、不同的配置,都会导致同样的文件 ETag可能是不相等的。当然了,如果你能限制上述信息都一样,也可以使用ETag,并不绝对。
    • Last-Modified时间精度是秒的问题,如果1s内修改了, Last-Modified不会更改,eTag是使用了摘要算法,可以及时刷新

3、不同行为引起的缓存

  • 在URI输入栏中输入然后回车/通过书签访问

    • 浏览器发现该资源已经缓存了而且没有过期(通过Expires头部或者Cache-Control头部),没有跟服务器确认,而是直接使用了浏览器缓存的内容。其中响应内容和之前的响应内容一模一样,例如其中的Date时间是上一次响应的时间。所以我们也能看到该资源的Size为from cache
  • F5/点击工具栏中的刷新按钮/右键菜单重新加载

    • F5会让浏览器无论如何都发一个HTTP Request给Server,即使先前的响应中有Expires头部
  • Ctl+F5

    • Ctrl+F5要的是彻底的从Server拿一份新的资源过来,所以不光要发送HTTP request给Server,而且这个请求里面连If-Modified-Since/If-None-Match都没有,这样就逼着Server不能返回304,而是把整个资源原原本本地返回一份,这样,Ctrl+F5引发的传输时间变长了,自然网页Refresh的也慢一些。我们可以看到该操作返回了200,并刷新了相关的缓存控制时间。
    • 为了保证拿到的是从Server上最新的,Ctrl+F5不只是去掉了If-Modified-Since/If-None-Match,还需要添加一些HTTP Headers。按照HTTP/1.1协议,Cache不光只是存在Browser终端,从Browser到Server之间的中间节点(比如Proxy)也可能扮演Cache的作用,为了防止获得的只是这些中间节点的Cache,需要告诉他们,别用自己的Cache敷衍我,往Upstream的节点要一个最新的copy吧。
    • 在Chrome 51 中会包含两个头部信息, 作用就是让中间的Cache对这个请求失效,这样返回的绝对是新鲜的资源。Cache-Control: no-cache Pragma: no-cache

三、 跨域问题

1、原理

协议 | 站点域名 | 端口号 有一个不一样就是跨域

2、表现

服务端跨域请求的资源无法共享
只要不同源就不能共享localStorage的数据

3、解决方案

1) jsonP,JSONP只支持GET请求,优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
2) Cros,CORS支持所有类型的HTTP请求
3) iFrame嵌套
4) postMessage:postMessage(data,origin)方法允许来自不同源的脚本采用异步方式进行通信,可以实现跨文本档、多窗口、跨域消息传递

*   safari,父页面无法向iframe里的跨域页面传递信息,用url传值的方法来实现跨域存储功能,可以用页面url参数(safari浏览器可以支持超过64k个字符的长度)

5) 新的跨域策略:跨域隔离 COOP、COEP

四、 并发问题

1、 现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

  • HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接

    • 虽然标准中没有设定,某些服务器对 Connection: keep-alive 的 Header 进行了支持。
  • HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接

2、 一个 TCP 连接是可以发送多个 HTTP 请求的。
3、 一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?

  • HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。
  • HTTP/1.1 规范中规定了 Pipelining

    • 一个支持持久连接的客户端可以在一个连接中发送多个请求(不需要等待任意请求的响应)。收到请求的服务器必须按照请求收到的顺序发送响应。
    • 但是这个功能在浏览器中默认是关闭的。由于 HTTP/1.1 是个文本协议,同时返回的内容也并不能区分对应于哪个发送的请求,所以顺序必须维持一致
    • 现代浏览器默认是不开启 HTTP Pipelining
    • 问题

      • 一些代理服务器不能正确的处理 HTTP Pipelining。
      • 正确的流水线实现是复杂的。
      • Head-of-line Blocking 连接头阻塞
    • 优化

      • 维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。
      • 和服务器建立多个 TCP 连接。
  • HTTP2 提供了 Multiplexing 多路传输特性

    • 可以在一个 TCP 连接中同时完成多个 HTTP 请求

4、 为什么有的时候刷新页面不需要重新建立 SSL 连接?

  • TCP 连接有的时候会被浏览器和服务端维持一段时间。TCP 不需要重新建立,SSL 自然也会用之前的。

5、 浏览器对同一 Host 建立 TCP 连接到数量有没有限制?

  • Chrome 最多允许对同一个 Host 建立六个 TCP 连接
  • 如果图片都是 HTTPS 连接并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商量能不能用 HTTP2

    • 能的话就使用 Multiplexing 功能在这个连接上进行多路传输
    • 用不了 HTTP2 或 https

      • 浏览器就会在一个 HOST 上建立多个 TCP 连接,连接数量的最大限制取决于浏览器设置
      • 这些连接会在空闲的时候被浏览器用来发送新的请求
      • 如果所有的连接都正在发送请求呢?那其他的请求就只能等等了。

五、请求相关

1、 get post 区别

*   Get 方法的含义是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。
*   Post向 URI 指定的资源提交数据,数据就放在报文的 body 里。
*   GET 方法就是安全且幂等的, POST 都不是
*   安全和幂等的概念:
    *   在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
    *   所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。

2、 常用端口号

  • 200

    • 「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
    • 「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
  • 300

    • 301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
    • 302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
    • 301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
    • 304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。
  • 400

    • 「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
  • 500

    • 500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
    • 「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
    • 「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
    • 「503 Service Unavailable」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

六、边界问题

*   A、B 机器正常连接后,B 机器突然重启,问 A 此时处于 TCP 什么状态
    *   [https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/21](https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/21)
*   一个TCP连接可以发多少个HTTP请求
    *   [https://maimai.cn/article/detail?fid=1565594485&efid=2XGge6_3eNs_d2tiQsBWRw&use_rn=1](https://maimai.cn/article/detail?fid=1565594485&efid=2XGge6_3eNs_d2tiQsBWRw&use_rn=1)
    

七、参考链接

*   [【手动加精】硬核!30 张图解 HTTP 常见的面试题](https://www.cnblogs.com/xiaolincoding/p/12442435.html)
*   [HTTP 的发展和演变](https://www.cnblogs.com/xiaolincoding/p/12442435.html)
*   [一个TCP连接可以发多少个HTTP请求](https://maimai.cn/article/detail?fid=1565594485&efid=2XGge6_3eNs_d2tiQsBWRw&use_rn=1)
*   [浏览器HTTP缓存机制](https://juejin.cn/post/6844903554587574285)
*   [强制缓存和协商缓存](https://juejin.cn/post/6844903838768431118)
*   [缓存优先级](https://segmentfault.com/q/1010000022541364)
*   [http 差异](https://zhuanlan.zhihu.com/p/102561034)
*   [HTTP 0.9 HTTP 1.0 HTTP 1.1 HTTP 2.0区别](https://www.cnblogs.com/wupeixuan/p/8642100.html)
*   [HTTP缓存控制小结](https://imweb.io/topic/5795dcb6fb312541492eda8c)
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 2 收藏 2 评论 1

Logic 发布了文章 · 2020-12-23

原型链的发展设计思路与常规应用方式初探

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
  • 历史

    • 背景

      • 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。
    • 简单设计

      • 工程师Brendan Eich负责开发这种新语言,他觉得,没必要设计得很复杂,这种语言只要能够完成一些简单操作就够了,比如判断用户有没有填写表单。
    • 万物皆对象

      • 1994年正是面向对象编程(object-oriented programming)最兴盛的时期,C++是当时最流行的语言,而Java语言的1.0版即将于第二年推出,Sun公司正在大肆造势。Brendan Eich无疑受到了影响,Javascript里面所有的数据类型都是对象(object)
    • 继承与不要类

      • 如果真的是一种简易的脚本语言,其实不需要有"继承"机制。但是,Javascript里面都是对象,必须有一种机制,将所有对象联系起来。所以,Brendan Eich最后还是设计了"继承"。
      • 考虑不引入类,因为一旦有了"类",Javascript就是一种完整的面向对象编程语言了,这好像有点太正式了,而且增加了初学者的入门难度 (在 ES2015/ES6 中引入了 class 关键字,但那只是语法糖,JavaScript 仍然是基于原型的)
    • 原型与构造函数

      • Brendan Eich把new命令引入了Javascript,用来从原型对象生成一个实例对象,C++和Java使用new命令时,都会调用"类"的构造函数(constructor)。他就做了一个简化的设计,在Javascript语言中,new命令后面跟的不是类,而是构造函数。
    • new运算符的缺点

      • 无法共享属性和方法,每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。
    • prototype属性的引入

      • 为了解决new的缺点,Brendan Eich决定为构造函数设置一个prototype属性。
      • 这个属性包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
      • 实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。
  • 原理

    • 继承与链式查找

      • 当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例
    • 构造函数、原型对象、实例

      • 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针
  • 原理的边界理解

    • 原型做什么

      • 原型是为了共享多个对象之间的一些共有特性(属性或方法)
    • 最顶层的原型对象

      • 这个对象就是Object.prototype,这个对象中保存了最常用的方法,如toString、valueOf、hasOwnProperty等,因此我们才能在任何对象中使用这些方法
    • 构造函数

      • 函数的构造调用(注意,我们不把它叫做构造函数,因为JavaScript中同样没有构造函数的概念,所有的函数都是平等的,只不过用来创建对象时,函数的调用方式不同而已)
    • 属性遮蔽 (property shadowing)

      • 对象自身的属性会优先与原型链上的同名属性被访问到,比如:o.b, b是o的自身属性吗?是的,原型上也有一个'b'属性,但是它不会被访问到。
    • this指向

      • 当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。注意闭包与箭头函数
    • 创建非拷贝

      • JavaScript的对象创建不存在拷贝,对象的原型实际上也是一个对象,它和对象本身是完全独立的两个对象
    • 委托非继承

      • 继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。
  • 关键属性介绍

    • prototype

      • 每个构造函数都有一个prototype原型对象
      • prototype是函数才具有的属性
      • 被构造函数创建的实例对象的 [[Prototype]] 指向 func 的 prototype 属性。Object.prototype 属性表示 Object 的原型对象。
      • 默认情况下,new 一个函数创建出的对象,其原型都指向这个函数的prototype属性。
    • proto 与getPrototypeOf+setPrototypeOf

      • 每个对象都有一个__proto__属性,并且指向它的prototype原型对象
      • someObject.[[Prototype]] 符号是用于指向 someObject 的原型。从 ECMAScript 6 开始,[[Prototype]] 可以通过 Object.getPrototypeOf() 和 Object.setPrototypeOf() 访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性 __proto__。
      • __proto__属性指向问题

        • 字面量创建的对象

          • 创建: var a = {}
          • 指向: obj.__proto__ === Object.prototype; a.__proto__ === a.constructor.prototype
        • 构造器方式

          • 创建: var A = function (); var a = new A()
          • 指向: a.__proto__ === A.prototype; a.__proto__ === a.constructor.prototype
        • Object.create方式

          • 创建: var a1 = {} var a2 = Object.create(a1)
          • 指向: a2.__proto__ === a1; a.__proto__ !== a.constructor.prototype
    • prototype与__proto__

      • prototype是函数才具有的属性
      • __proto__是每个对象都具有的属性,但是不是规范属性,只有部分浏览器实现了,标准属性是someObject.[[Prototype]]
    • constructor

      • 原型对象上默认有一个属性constructor,该属性也是一个指针,指向其相关联的构造函数。
      • prototype原型对象里的constructor指向构造函数本身
    • hasOwnProperty 与 Object.keys()

      • JavaScript 中唯一2个处理属性并且不会遍历原型链的方法。
  • 边界情况

      1. 对于JavaScript中的内置对象,如String、Number、Array、Object、Function等,因为他们是native代码实现的,他们的原型打印出来都是ƒ () { [native code] }
      1. 内置对象本质上也是函数,所以可以通过他们创建对象,创建出的对象的原型指向对应内置对象的prototype属性,最顶层的原型对象依然指向Object.prototype。
      1. Object.create(null) 创建出的对象,不存在原型。 Object.create(null).__proto__ == undefined
  • 创建对象的方法

    • 1.字面量方式, var obj = {};

      • 当通过字面量方式创建对象时,它的原型就是Object.prototype。
      • 虽然我们无法直接访问内置属性[[Prototype]],但我们可以通过Object.getPrototypeOf()或对象的__proto__获取对象的原型。
      • Object.getPrototypeOf(obj) === Object.prototype;
      • obj.__proto__ === Object.prototype;
    • 2.函数的构造调用, var obj = new f();

      • javaScript在定义一个函数时,同时为这个函数定义了一个 默认的prototype属性,所有共享的属性或方法,都放到这个属性所指向的对象中.
      • 通过一个函数的构造调用创建的对象,它的原型就是这个函数的prototype指向的对象。
      • obj.__proto__ === f.prototype
    • 3.Object.create(), var obj2 = Object.create(obj);

      • 这个方法会以你传入的对象作为创建出来的对象的原型。
      • 这种方式还可以模拟对象的“继承”行为。
      • obj2.__proto__ === obj;
  • 应用

    • 实现继承

      • 构造函数的继承

        • 1、 构造函数绑定,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:Animal.apply(this, arguments);
        • 2、 prototype模式,"猫"的prototype对象,指向一个Animal的实例; 【注意!!!如果替换了prototype对象,那么,下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数。不然容易造成原型链紊乱】Cat.prototype = new Animal();  Cat.prototype.constructor = Cat;
        • 3、 改进prototype模式,让Cat()跳过 Animal(),直接继承Animal.prototype;

          • Cat.prototype = Animal.prototype; Cat.prototype.constructor = Cat;
          • 优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。
          • 缺点是 Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype。
        • 4、 利用空对象作为中介

          • var F = function(){}; F.prototype = Animal.prototype;
          • Cat.prototype = new F(); Cat.prototype.constructor = Cat;
          • F是空对象,所以几乎不占内存。这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
        • 5、  拷贝继承,把父对象的所有属性和方法,拷贝进子对象

          • function extend2(Child, Parent) {

            • var p = Parent.prototype; var c = Child.prototype;
            • for (var i in p) { c[i] = p[i]; }
            • c.uber = p; }
      • 非构造函数的继承

        • object()方法,使用prototype链

          • function object(o) { function F() {} F.prototype = o; return new F(); }
          • 把子对象的prototype属性,指向父对象,从而使得子对象与父对象连在一起
        • 浅拷贝, 把父对象的属性,全部拷贝给子对象,也能实现继承
        • 深拷贝, 递归调用"浅拷贝"
    • 属性方法的全局作用域

      • vue.prototype.xxx
    • 如何体现原型的扩展性-插件机制 JQ / zepto

      • 思考

        • 为何要把原型方法放在$.fn?:扩展插件。(第一,构造函数的 prototype 肯定得指向能扩展的对象;第二,$.fn 肯定得指向能扩展的对象)
      • 好处:

        • 1,只有$会暴露在window全局变量
        • 2,将插件扩展统一到 $.fn.xxx 这一个接口,方便使用
    • instanceOf

      • 遍历原型链查找是否是某个原型对象的实例
    • this

      • this指向问题

        • 当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。注意闭包与箭头函数
      • class中的this指向
      • bind

        • 改变this指向,并返回一个函数
        • 通过原型链取到某些特殊的方法实现拼接参数

          • 思路:通过构造函数取到特殊方法实现拼接参数+apply
          • Array.prototype.slice.call(arguments);
      • call / apply
    • new // new运算符及背后工作原理

      • new后跟构造函数
      • 1,一个新对象被创建,它继承自func.prototype(构造函数的原型对象)
      • 2,构造函数func被执行,执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例
      • 3,如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果,如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象
  • 发散思考

  • 参考链接

【By: 360手机助手团队-XTeam】
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 1 收藏 1 评论 0

Logic 发布了文章 · 2020-12-23

弹窗滚动穿透原理与解决方案的探讨

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

是什么

先解释下什么是滚动穿透

页面滑出了一个弹窗,我们用手指触摸屏幕滑动时,会发现弹窗下面的内容还是在滚动。这个现象就是滚动穿透

为什么

为什么会有这个现象呢

原因:使用系统的滚动,html和body的高度超出窗口的高度,自动使用系统滚动,这个滚动会导致滚动穿透。

如下图,最顶上是视窗的高度,最底下是body的高度
image.png

  • MDN上这样解释这个问题

去康康文档
image.png
image.png

怎么办

1、body height 100% + 区域内滚动

  1. 在body下的div上使用自己的height:100%; overflow: auto/scoll;(在IOS上不流畅需要加 :-webkit-overflow-scrolling: touch;)
  2. .给html,body 增加{position:fixed;with100%;height:100%; } 使html,body不会再使用系统滚动;
  3. 发现在安卓手机上完美实现,但是IOS的滚动机制让使人头大,依然可以穿透,这时我们在弹窗后需要把滚动的div上加上 overflow:hidden; 去掉 -webkit-overflow-scrolling: touch; 属性在关闭弹窗的时候恢复为 overflow: auto; 再加上-webkit-overflow-scrolling: touch; 可以实现IOS的兼容;至此滚动穿透就被解决了。

2、touchmove + preventDefault

touchmove + preventDefault
打开模态框时,阻止touchmove
缺陷: 模态框内的滚动内容失去滚动效果。

3、标记位置,弹性容器

1、模态框打开前记录背景的移动位置,关闭后回弹回去
image.png
2、为模态框动态绑定区域内滚动样式
image.png
缺点:无法处理模态框透明时候的场景

4、锁定容器,内容偏移

模态框打开后,在背景层监听容器滚动事件,时刻触发回弹
image.png
image.png
demo发现,回弹会触发闪屏,考虑定位与优化

闪屏分析

分析每一次滚动间隔是否大于一帧时长
image.png
结果如图
image.png
image.png

结合刷帧策略,判断是scroll事件触发的时候触碰了刷帧的反向回弹
image.png
考虑是每一帧做一次回弹定位校准, 考虑使用requestAnimationFrame

image.png

【By: 360手机助手团队-XTeam】
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】
查看原文

赞 1 收藏 1 评论 0

Logic 关注了专栏 · 2020-12-22

SegmentFault 行业快讯

第一时间为开发者提供行业相关的实时热点资讯

关注 63607

Logic 关注了专栏 · 2020-12-22

民工哥技术之路

公众号:民工哥技术之路、《Linux系统运维指南 从入门到企业实战》作者。专注系统架构、高可用、高性能、高并发,数据库、大数据、数据分析、Python技术、集群中间件、后端等开源技术分享。

关注 32004

Logic 关注了专栏 · 2020-12-22

concent

concent,一个内置依赖收集系统,并兼具0入侵、可预测、渐进式、高性能特点的react状态管理方案。

关注 9297

认证与成就

  • 获得 9 次点赞
  • 获得 2 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 2 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2020-12-22
个人主页被 627 人浏览