二本获得阿里实习 offer 经历-宝藏篇(上)

986 阅读48分钟

(因字数限制分为上下文,最后的思维导图整理在下篇)

系列如下:觉得有用要点赞!✨

前言

滴滴滴!自己整了一年半载的知识点回顾,又历经了 3 个月的春招实习面试,呜呜呜呜呜(一直呜呜呜),幸运的是自己也最终获得到阿里的 offer。在期间受到了很多小友的帮助,巩固了自身的前端基础知识。平时自己也有记录和整理对应的知识,以此机会,总结这段时间来 "挖掘" 这一些让我成功 “上岸” 的宝藏吧。「笔者真实经历的面试题都含括在内了喔!」

备注:每个宝藏的开头都有笔者粗略的思维导图噢,可以看着思维导图做自身的查漏补缺(小弟我就是这么做的!)

在整理完对应的思维导图后,因近期一直在准备软考还有其他各种事情,这一篇自己拖了好久好久才写耶。我个人建议是这篇文章可以对自己面试的要点做查漏补缺,而不是详细的知识点字典噢!对某个要点自己过遍脑子,觉得必要可以自己整理自身特定的读书笔记!那就开始开始开始!


image.png

目录

笔者在期间总结如下几个方面,有需要的小友们可以直接点击段落内容获取所需的 “宝藏” 喔。要是只所需思维导图,直接到文章结尾自取噢!「有用就要点赞!」

image.png

@[TOC]

HTML

image.png

导入

link 和 @import区别

- 从属关系区别。 
  - @import 是 CSS 提供的语法规则,只有导入样式表的作用;
  - link 是 HTML 提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性、引入网站图标等。
- 加载顺序区别。加载页面时
  - link 标签引入的 CSS 被同时加载;
  - @import 引入的 CSS 将在页面加载完毕后被加载。
- 兼容性区别。
  - @import 是 CSS2.1 才有的语法,故只可在 IE5+ 才能识别;
  - link 标签作为 HTML 元素,不存在兼容 性问题。
- DOM 可控性区别。
  - 可以通过 JS 操作 DOM ,插入 link 标签来改变样式;
  - 由于 DOM 方法是基于文档的,无法使用 @import 的方式插入样式。

SEO

- 合理的 title、description、keywords
  - 搜索对着三项的权重逐个减小。
  - title 值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面 title 要有所不同
  - description 把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面 description 有所不同
  - keywords 列举出重要关键词即可。
- 语义化的 HTML 代码,符合 W3C 规范:语义化代码让搜索引擎容易理解网页。
- 重要内容 HTML 代码放在最前:搜索引擎抓取 HTML 顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容肯定被抓取。
- 重要内容不要用 js 输出:爬虫不会执行 js 获取内容
- 少用 iframe:搜索引擎不会抓取 iframe 中的内容
- 非装饰性图片必须加 alt
- 提高网站速度:网站速度是搜索引擎排序的一个重要指标

常见 meta

<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。
<meta> 标签位于文档的头部,不包含任何内容。<meta> 标签的属性定义了与文档相关联的名称/值对。

<!DOCTYPE html>  H5标准声明,使用 HTML5 doctype,不区分大小写
<head lang=”en”> 标准的 lang 属性写法
<meta charset=’utf-8′>    声明文档使用的字符编码
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/>   优先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超过150个字符”/>       页面描述
<meta name=”keywords” content=””/>      页面关键词者
<meta name=”author” content=”name, email@gmail.com”/>    网页作
<meta name=”robots” content=”index,follow”/>      搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 为移动设备添加 viewport
<meta name=”apple-mobile-web-app-title” content=”标题”> iOS 设备 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/>  添加到主屏后的标题(iOS 6 新增)
是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 广告条 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/>  设置苹果工具栏颜色
<meta name=”renderer” content=”webkit”>  启用360浏览器的极速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>     避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” />    不让百度转码
<meta name=”HandheldFriendly” content=”true”>     针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓
<meta name=”MobileOptimized” content=”320″>   微软的老式浏览器
<meta name=”screen-orientation” content=”portrait”>   uc强制竖屏
<meta name=”x5-orientation” content=”portrait”>    QQ强制竖屏
<meta name=”full-screen” content=”yes”>              UC强制全屏
<meta name=”x5-fullscreen” content=”true”>       QQ强制全屏
<meta name=”browsermode” content=”application”>   UC应用模式
<meta name=”x5-page-mode” content=”app”>    QQ应用模式
<meta name=”msapplication-tap-highlight” content=”no”>    windows phone 点击无高光
设置页面不缓存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>

attribute 和 property 的区别

- attribute 是 dom 元素在文档中作为 html 标签拥有的属性;
- property 就是 dom 元素在 js 中作为对象拥有的属性。
  - 对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的,但是对于自定义的属性来说,他们是不同步的。

构建页面

构建页面分为:渐进增强,优雅降级。

优化

前端性能优化主要是为了提高页面的加载速度,优化用户的访问体验。

- 页面的内容方面
(1)通过文件合并、css 雪碧图、使用 base64 等方式来减少 HTTP 请求数,避免过多的请求造成等待的情况。
(2)通过 DNS 缓存等机制来减少 DNS 的查询次数。
(3)通过设置缓存策略,对常用不变的资源进行缓存。
(4)使用延迟加载的方式,来减少页面首屏加载时需要请求的资源。延迟加载的资源当用户需要访问时,再去请求加载。
(5)通过用户行为,对某些资源使用预加载的方式,来提高用户需要访问资源时的响应速度。

- 服务器方面
(1)使用 CDN 服务,来提高用户对于资源请求时的响应速度。
(2)服务器端启用 Gzip、Deflate 等方式对于传输的资源进行压缩,减小文件的体积。
(3)尽可能减小 cookie 的大小,并且通过将静态资源分配到其他域名下,来避免对静态资源请求时携带不必要的 cookie

-  CSS 和 JavaScript 方面
(1)把样式表放在页面的 head 标签中,减少页面的首次渲染的时间。
(2)避免使用 @import 标签。
(3)尽量把 js 脚本放在页面底部或者使用 defer 或 async 属性,避免脚本的加载和执行阻塞页面的渲染。
(4)通过对 JavaScript 和 CSS 的文件进行压缩,来减小文件的体积。

HTML5

新特性

  • canvas

  • 存储

  • 语义化标签

    (1) 用正确的标签做正确的事情。
    (2) html 语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;
    (3) 即使在没有样式 CSS 情况下也以一种文档格式显示,并且是容易阅读的;
    (4) 搜索引擎的爬虫也依赖于 HTML 标记来确定上下文和各个关键字的权重,利于 SEO ;
    (5) 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解,无障碍。
    
  • 媒体

移除元素

- 纯表现的元素:basefont,big,center,font, s,strike,tt,u;
- 对可用性产生负面影响的元素:frame,frameset,noframes;

兼容问题

(1)IE8/IE7/IE6 支持通过 document.createElement 方法产生的标签,可以利用这一特性让这些浏览器,支持 HTML5 新标签,浏览器支持新标签后,还需要添加标签默认的样式。

(2)当然也可以直接使用成熟的框架,比如 html5shiv ;
<!--[if lt IE 9]>
	<script> src="https://cdn.jsdelivr.net/npm/html5shiv/dist/html5shiv.min.js"</script>
 <![endif]-->

[if lte IE 9]……[endif] 判断 IE 的版本,限定只有 IE9 以下浏览器版本需要执行的语句。

元素

HTML4

需熟悉常见的行内元素及块级元素。
- 行内元素
- 块级元素

HTML5

- 七类元素
  - Metadata 
  - Flow 
  - Sectioning 
  - Heading 
  - Phrasing 
  - Embedded 
  - Interactive

空元素

标签内没有内容的 HTML 标签被称为空元素。空元素是在开始标签中关闭的。

常见的空元素有:`br``hr``img``input``link``meta`

文档

DOCTYPE

标准模式与兼容模式

  • 标准模式的渲染方式和 JS 引擎的解析方式都是以该浏览器支持的最高标准运行。
  • 兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。

文档类型/区别

  • SGML 是标准通用标记语言,是一种定义电子文档结构和描述其内容的国际标准语言,是所有电子文档标记语言的起源。

  • HTML 是超文本标记语言,主要是用于规定怎么显示网页。

  • XML 是可扩展标记语言是未来网页语言的发展方向。

    - XML 和 HTML 的最大区别就在于 XML 的标签是可以自己创建的,数量无限多,而 HTML 的标签都是固定的而且数量有限。
    - XHTML 也是现在基本上所有网页都在用的标记语言,他其实和 HTML 没什么本质的区别,标签都一样,用法也都一样,就是比 HTML 更严格,比如标签必须都用小写,标签都必须有闭合标签等。
    

image.png

CSS

image.png

布局方式

两栏布局

两栏布局一般指的是页面中一共两栏,左边固定,右边自适应的布局,一共有四种实现的方式。

- 以左边宽度固定为 200px 为例
  - (1)利用浮动,将左边元素宽度设置为 200px,并且设置向左浮动。将右边元素的 margin-left 设置为 200px,宽度设置为 auto(默认为 auto,撑满整个父元素)。
  - (2)第二种是利用 flex 布局,将左边元素的放大和缩小比例设置为 0,基础大小设置为 200px。将右边的元素的放大比例设置为 1,缩小比例设置为 1,基础大小设置为 auto。
  - (3)第三种是利用绝对定位布局的方式,将父级元素设置相对定位。左边元素设置为 absolute 定位,并且宽度设置为 200px。将右边元素的 margin-left 的值设置为 200px。
  - (4)第四种还是利用绝对定位的方式,将父级元素设置为相对定位。左边元素宽度设置为 200px,右边元素设置为绝对定位,左边定位为 200px,其余方向定位为 0

三栏布局

三栏布局一般指的是页面中一共有三栏,左右两栏宽度固定,中间自适应的布局,一共有五种实现方式。

- 这里以左边宽度固定为 100px,右边宽度固定为 200px 为例。
  - (1)利用绝对定位的方式,左右两栏设置为绝对定位,中间设置对应方向大小的 margin 的值。
  - (2)利用 flex 布局的方式,左右两栏的放大和缩小比例都设置为 0,基础大小设置为固定的大小,中间一栏设置为 auto。
  - (3)利用浮动的方式,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的 margin 值,注意这种方式,中间一栏必须放到最后。
  - (4)圣杯布局,利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。圣杯布局中间列的宽度不能小于两边任意列的宽度,而双飞翼布局则不存在这个问题。
  - (5)双飞翼布局,双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的。

静态布局

就静态页面的布局

流式布局

页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。

自适应布局

自适应布局的特点是分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。可以把自适应布局看作是静态布局的一个系列。

响应式布局

随着 CSS3 出现了媒体查询技术,又出现了响应式设计的概念。响应式设计的目标是确保一个页面在所有终端上(各种尺寸的 PC、手机、手表、冰箱的 Web 浏览器等等)都能显示出令人满意的效果,对 CSS 编写者而言,在实现上不拘泥于具体手法,分别为不同的屏幕分辨率定义布局,即页面元素宽度随着窗口调整而自动适配。

弹性布局

flex!!!!!自己去看教程,哥!

CSS3 新特性

伪类 | 伪元素

- css3 中使用单冒号来表示伪类,用双冒号来表示伪元素。
- 伪类一般匹配的是元素的一些特殊状态,如 hover、link 等伪元素一般匹配的特殊的位置,比如 after、before 等。

opacity

透明度

媒体查询

- 外联式语法
- 内嵌式语法

动画

  • transform
  • transition
  • animation

阴影

渐变

优化

加载性能

1)css 压缩:将写好的 css 进行打包压缩,可以减少很多的体积。    
(2)css 单一样式:当需要下边距和左边距的时候,很多时候选择: margin: top 0 bottom 0;但 margin-bottom: bottom; margin-left:left; 执行的效率更高。    
(3)减少使用 @import ,而建议使用 link,因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载。    
(4)雪碧图

选择器性能

1)关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分)。CSS 选择符是从右到左进行匹配的。当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等;    
(2)如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。    
(3)避免使用通配规则,如 *{} 计算次数惊人!只对需要用到的元素进行选择。    
(4)尽量少的去对标签进行选择,而是用 class。    
(5)尽量少的去使用后代选择器,降低选择器的权重值。后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素。    
(6)了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则。

渲染性能

1)慎重使用高性能属性:浮动、定位。    
(2)尽量减少页面重排、重绘。    
(3)去除空规则:{}。空规则的产生原因一般来说是为了预留样式。去除这些空规则无疑能减少 css 文档体积。
(4)属性值为 0 时,不加单位。    
(5)属性值为浮动小数 0.,可以省略小数点之前的0。    
(6)标准化各种浏览器前缀:带浏览器前缀的在前。标准属性在后。    
(7)不使用 @import 前缀,它会影响css的加载速度。    
(8)选择器优化嵌套,尽量避免层级过深。    
(9)css 雪碧图,同一页面相近部分的小图标,方便使用,减少页面的请求次数,但是同时图片本身会变大,使用时,优劣考虑清楚,再使用。    
(10)正确使用 display 的属性,由于 display 的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能。    
(11)不滥用 web 字体。对于中文网站来说 WebFonts 可能很陌生,国外却很流行。web fonts 通常体积庞大,而且一些浏览器在下载 web fonts 时会阻塞页面渲染损伤性能。

维护性能

1)将具有相同属性的样式抽离出来,整合并通过 class 在页面中进行使用,提高 css 的可维护性。    
(2)样式与内容分离:将 css 代码定义到外部 css 中。
  • 兼容

各主流内核前缀:
mozilla 内核 ( firefox,flock 等) -moz
webkit 内核( safari,chrome 等) -webkit
opera 内核( opera 浏览器) -o
trident 内核( ie 浏览器) -ms

概念

CSS 加载渲染

- 不阻塞 DOM解析
- 阻塞 DOM 渲染
- 阻塞 JS

继承

每一个属性在定义中都给出了这个属性是否具有继承性,一个具有继承性的属性会在没有指定值的时候,会使用父元素的同属性的值来作为自己的值。    
一般具有继承性的属性有,字体相关的属性,font-sizefont-weight 等。文本相关的属性,colortext-align等。表格的一些布局属性、列表属性如 list-style 等。还有光标属性 cursor、元素可见性 visibility。        
不是继承属性的时候,我们也可以通过将它的值设置为 inherit 来使它从父元素那获取同名的属性值来继承。

BFC

BFC 指的是块级格式化上下文,一个元素形成了 BFC 之后,那么它内部元素产生的布局不会影响到外部元素,外部元素的布局也不会影响到 BFC 中的内部元素。一个 BFC 就像是一个隔离区域,和其他区域互不影响。
一般来说根元素是一个 BFC 区域,浮动和绝对定位的元素也会形成 BFC,display 属性的值为 inline-block、flex 这些属性时也会创建 BFC。还有就是元素的 overflow 的值不为 visible 时都会创建 BFC。

IFC

IFC 指的是行级格式化上下文,它有这样的一些布局规则:

(1)行级上下文内部的盒子会在水平方向,一个接一个地放置。    
(2)当一行不够的时候会自动切换到下一行。    
(3)行级上下文的高度由内部最高的内联盒子的高度决定。

替换/非替换元素

选择符

1id 选择器(#myid)
(2)类选择器(.myclassname)
(3)标签选择器(div,h1,p)
(4)后代选择器(h1 p)
(5)相邻后代选择器(子)选择器(ul>li)
(6)兄弟选择器(li~a)
(7)相邻兄弟选择器(li+a)
(8)属性选择器(a[rel="external"])
(9)伪类选择器(a:hover,li:nth-child)
(10)伪元素选择器(::before::after)
(11)通配符选择器(*)

优先级

优化

回流/重绘

1. 避免频繁使用 style,而是采用修改 class 的方式。
2. 将动画效果应用到 position 属性为 absolute 或 fixed 的元素上。
3. 也可以先为元素设置 display: none,操作结束后再把它显示出来。因为在 display 属性为 none 的元素上进行的 DOM 操作不会引发回流和重绘
4. 使用 createDocumentFragment 进行批量的 DOM 操作。
5. 对于 resize、scroll 等进行防抖/节流处理。
6. 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
7. 利用 CSS3 的transform、opacity、filter 这些属性可以实现合成的效果,也就是 GPU 加速。
  • 多端优化

属性

  • display 值

  • 盒模型

    • 如何转换
  • em/rem

  • position 值的定点

    absolute:生成绝对定位的元素,相对于值不为 static 的第一个父元素的 padding box 进行定位,也可以理解为离自己这一级元素最近的一级 position 设置为 absolute 或者 relative 的父元素的 padding box 的左上角为原点的。
    fixed(老IE不支持):生成绝对定位的元素,相对于浏览器窗口进行定位。
    relative:生成相对定位的元素,相对于其元素本身所在正常位置进行定位。
    static:默认值。没有定位,元素出现在正常的流中(忽略 top,bottom,left,right,z-index 声明)。
    inherit:规定从父元素继承 position 属性的值。
    
  • border

    1border-width 却不支持百分比。
    (2border-style 的默认值是 none,有一部分人可能会误以为是 solid。这也是单纯设置 border-widthborder-color 没有边框显示的原因。
    (3border-style: double 的表现规则:双线宽度永远相等,中间间隔±1。
    (4)border-color 默认颜色就是 color 色值。
    (5)默认 background 背景图片是相对于 padding box 定位的。
    
  • line-height

    1)对于非替换元素的纯内联元素,其可视高度完全由 line-height 决定。对于文本这样的纯内联元素,line-height 就是高度计算的基石,用专业说法就是指定了用来计算行框盒子高度的基础高度。
    (2)内联元素的高度由固定高度和不固定高度组成,这个不固定的部分就是这里的“行距”。换句话说,line-height 之所以起作用,就是通过改变“行距”来实现的。在 CSS 中,“行距”分散在当前文字的上方和下方,也就是即使是第一行文字,其上方也是有“行距”的,只不过这个“行距”的高度仅仅是完整“行距”高度的一半,因此,也被称为“半行距”。
    (3)行距 = line-height-font-size。
    (4border 以及 line-height 等传统 CSS 属性并没有小数像素的概念。如果标注的是文字上边距,则向下取整;如果是文字下边距,则向上取整。
    (5)对于纯文本元素,line-height 直接决定了最终的高度。但是,如果同时有替换元素,则 line-height 只能决定最小高度。
    (6)对于块级元素,line-height 对其本身是没有任何作用的,我们平时改变 line-height,块级元素的高度跟着变化实际上是通过改变块级元素里面内联级别元素占据的高度实现的。
    (7line-height 的默认值是 normal,还支持数值、百分比值以及长度值。为数值类型时,其最终的计算值是和当前 font-size 相乘后的值。为百分比值时,其最终的计算值是和当前 font-size 相乘后的值。为长度值时原意不变。
    (8)如果使用数值作为 line-height 的属性值,那么所有的子元素继承的都是这个值;但是,如果使用百分比值或者长度值作为属性值,那么所有的子元素继承的是最终的计算值。
    (9)无论内联元素 line-height 如何设置,最终父级元素的高度都是由数值大的那个 line-height 决定的。
    (10)只要有“内联盒子”在,就一定会有“行框盒子”,就是每一行内联元素外面包裹的一层看不见的盒子。然后,重点来了,在每个“行框盒子”前面有一个宽度为 0 的具有该元素的字体和行高属性的看不见的“幽灵空白节点”。
    

清除浮动

  • 设置父级

    • 设置 BFC

      浮动
      overflow
      inline-block
      
  • after 伪类

    • a 标签伪类

      a 标签有四种状态:链接访问前、链接访问后、鼠标滑过、激活,分别对应四种伪类: link:visited:hover:active

垂直居中方法

对于宽高固定的元素
(1)我们可以利用 margin:0 auto 来实现元素的水平居中。
(2)利用绝对定位,设置四个方向的值都为 0,并将 margin 设置为 auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。
(3)利用绝对定位,先将元素的左上角通过 top:50% 和 left:50% 定位到页面的中心,然后再通过 margin 负值来调整元素的中心点到页面的中心。
(4)利用绝对定位,先将元素的左上角通过 top:50% 和 left:50% 定位到页面的中心,然后再通过 translate 来调整元素的中心点到页面的中心。
(5)使用 flex 布局,通过 align-items:center 和 justify-content:center 设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。

对于宽高不定的元素,上面的后面两种方法,可以实现元素的垂直和水平的居中。

包含块

包含块(containing block)就是元素用来计算和定位的一个框。
(1)根元素(很多场景下可以看成是`<html>`)被称为“初始包含块”,其尺寸等同于浏览器可视窗口的大小。
(2)对于其他元素,如果该元素的 position 是 relative 或者 static,则“包含块”由其最近的块容器祖先盒的 content box边界形成。
(3)如果元素 position:fixed,则“包含块”是“初始包含块”。
(4)如果元素 position:absolute,则“包含块”由最近的 position 不为 static 的祖先元素建立

flex

margin 重叠问题

margin 重叠指的是在垂直方向上,两个相邻元素的 margin 发生重叠的情况。

一般来说可以分为四种情形:

1. 第一种是相邻兄弟元素的 marin-bottommargin-top 的值发生重叠。这种情况下我们可以通过设置其中一个元素为 BFC 来解决。
2. 第二种是父元素的 margin-top 和子元素的 margin-top 发生重叠。它们发生重叠是因为它们是相邻的,所以我们可以通过这一点来解决这个问题。我们可以为父元素设置 border-toppadding-top 值来分隔它们,当然我们也可以将父元素设置为 BFC 来解决。
3. 第三种是高度为 auto 的父元素的 margin-bottom 和子元素的 margin-bottom 发生重叠。它们发生重叠一个是因为它们相邻,一个是因为父元素的高度不固定。因此我们可以为父元素设置 border-bottompadding-bottom 来分隔它们,也可以为父元素设置一个高度,max-heightmin-height 也能解决这个问题。当然将父元素设置为 BFC 是最简单的方法。
4. 第四种情况,是没有内容的元素,自身的 margin-topmargin-bottom 发生的重叠。我们可以通过为其设置 borderpadding 或者高度来解决这个问题。

隐藏图片会不会加载

(1)元素的背景图片

元素本身设置 display:none,会请求图片 
父级元素设置 display:none,不会请求图片 
样式没有元素使用,不会请求
:hover 样式下,触发时请求

(2)img 标签图片任何情况下都会请求图片

省略溢出

  • 单行
/*单行文本溢出*/
p {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
  • 多行
/*多行文本溢出*/
p {
  position: relative;
  line-height: 1.5em;
  /*高度为需要显示的行数*行高,比如这里我们显示两行,则为3*/
  height: 3em;
  overflow: hidden;
}

p:after {
  content: '...';
  position: absolute;
  bottom: 0;
  right: 0;
  background-color: #fff;
}

元素隐藏

1)使用 display:none; 隐藏元素,渲染树不会包含该渲染对象,因此该元素不会在页面中占据位置,也不会响应绑定的监听事件。
(2)使用 visibility:hidden; 隐藏元素。元素在页面中仍占据空间,但是不会响应绑定的监听事件。
(3)使用 opacity:0; 将元素的透明度设置为 0,以此来实现元素的隐藏。元素在页面中仍然占据空间,并且能够响应元素绑定的监听事件。
(4)通过使用绝对定位将元素移除可视区域内,以此来实现元素的隐藏。
(5)通过 z-index 负值,来使其他元素遮盖住该元素,以此来实现隐藏。
(6)通过 clip/clip-path 元素裁剪的方法来实现元素的隐藏,这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
(7)通过 transform:scale(0,0) 来将元素缩放为 0,以此来实现元素的隐藏。这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。

css reset 和 normalize.css

- css reset 是最早的一种解决浏览器间样式不兼容问题的方案,它的基本思想是将浏览器的所有样式都重置掉,从而达到所有浏览器样式保持一致的效果。但是使用这种方法,可能会带来一些性能上的问题,并且对于一些元素的不必要的样式的重置,其实反而会造成画蛇添足的效果。

- 后面出现一种更好的解决浏览器间样式不兼容的方法,就是 normalize.css ,它的思想是尽量的保留浏览器自带的样式,通过在原有的样式的基础上进行调整,来保持各个浏览器间的样式表现一致。相对与 css reset,normalize.css 的方法保留了有价值的默认值,并且修复了一些浏览器的 bug,而且使用 normalize.css 不会造成元素复杂的继承链。

viewport

  • 布局视口

    第一个视口是布局视口,在移动端显示网页时,由于移动端的屏幕尺寸比较小,如果网页使用移动端的屏幕尺寸进行布局的话,那么整个页面的布局都会显示错乱。所以移动端浏览器提供了一个 layout viewport 布局视口的概念,使用这个视口来对页面进行布局展示,一般 layout viewport 的大小为 980px,因此页面布局不会有太大的变化,我们可以通过拖动和缩放来查看到这个页面。
    
  • 视觉视口

    第二个视口指的是视觉视口,visual viewport 指的是移动设备上我们可见的区域的视口大小,一般为屏幕的分辨率的大小。visual viewport 和 layout viewport的关系,就像是我们通过窗户看外面的风景,视觉视口就是窗户,而外面的风景就是布局视口中的网页内容。
    
  • 理想视口

    第三个视口是理想视口,由于 layout viewport 一般比 visual viewport 要大,所以想要看到整个页面必须通过拖动和缩放才能实现。所以又提出了 ideal viewport 的概念,ideal viewport 下用户不用缩放和滚动条就能够查看到整个页面,并且页面在不同分辨率下显示的内容大小相同。ideal viewport 其实就是通过修改 layout viewport 的大小,让它等于设备的宽度,这个宽度可以理解为是设备独立像素,因此根据 ideal viewport 设计的页面,在不同分辨率的屏幕下,显示应该相同。
    

image.png

JS

image.png

数据类型

七大基本数据类型

【语言基础】-大大的红宝书(三)

  • String

  • Boolean

  • Number

    以 0X、0x 开头的表示为十六进制。
    以 0、0O、0o 开头的表示为八进制。
    以 0B、0b 开头的表示为二进制格式
    
    • isNaN 和 Number.isNaN

      函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。
      函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,这种方法对于 NaN 的判断更为准确。
      
  • Null

  • Undefined

    undefined 与 undeclared 区别
    undefined 是已声明,未赋值。
    undeclared 是还未声明。
    
    undefinednull 区别
    undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefinednull主要用于赋值给一些可能会返回对象的变量,作为初始化。
    当我们对两种类型使用 typeof 进行判断的时候,Null 类型化会返回 “object”,这是一个历史遗留的问题。当我们使用双等号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false
  • Symbol

    代表创建后独一无二且不可变的数据类型
    
  • BigInt

    BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。
    

引用数据类型

判断数据类型方式

  • 常见三种

    • typeof

    • Object.prototype.toString.call()

      • [[Class]]

        所有 typeof 返回值为 "object" 的对象(如数组)都包含一个内部属性 [[Class]](我们可以把它看作一个内部的分类,而非传统的面向对象意义上的类)。
        这个属性无法直接访问,一般通过Object.prototype.toString(..) 来查看。
        
    • instanceof

  • 区别/优缺点

内置对象

js 中的内置对象主要指的是在程序执行前存在全局作用域里的由 js 定义的一些全局值属性、函数和用来实例化其他对象的构造函数对象。

标准内置对象的分类

(1)值属性,这些全局属性返回一个简单值,这些值没有自己的属性和方法。
    例如 InfinityNaNundefinednull 字面量

(2)函数属性,全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者。
    例如 eval()、parseFloat()、parseInt() 等

(3)基本对象,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象。
    例如 ObjectFunctionBooleanSymbolError 等

(4)数字和日期对象,用来表示数字、日期和执行数学计算的对象。
    例如 NumberMathDate5)字符串,用来表示和操作字符串的对象。
    例如 StringRegExp6)可索引的集合对象,这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象。
    例如 Array7)使用键的集合对象,这些集合对象在存储数据时会使用到键,支持按照插入顺序来迭代元素。
    例如 MapSetWeakMapWeakSet8)矢量集合,SIMD 矢量集合中的数据会被组织为一个数据序列。
    例如 SIMD 等

(9)结构化数据,这些对象用来表示和操作结构化的缓冲区数据,或使用 JSON 编码的数据。
    例如 JSON 等

(10)控制抽象对象
    例如 PromiseGenerator 等

(11)反射
    例如 ReflectProxy12)国际化,为了支持多语言处理而加入 ECMAScript 的对象。
    例如 IntlIntl.Collator 等

(13WebAssembly14)其他
    例如 arguments

模块化

发展历史

- 第一种是 CommonJS 方案,它通过 require 来引入模块,通过 module.exports 定义模块的输出接口。
    这种模块加载方案是服务器端的解决方案,它是以同步的方式来引入模块的,因为在服务端文件都存储在本地磁盘,所以读取非常快,所以以同步的方式加载没有问题。
    但如果是在浏览器端,由于模块的加载是使用网络请求,因此使用异步加载的方式更加合适。
- 第二种是 AMD 方案,这种方案采用异步加载的方式来加载模块,模块的加载不影响后面语句的执行,所有依赖这个模块的语句都定义在一个回调函数里,等到加载完成后再执行回调函数。require.js 实现了 AMD 规范。
- 第三种是 CMD 方案,这种方案和 AMD 方案都是为了解决异步模块加载的问题,sea.js 实现了 CMD 规范。它和 require.js的区别在于模块定义时对依赖的处理不同和对依赖模块的执行时机的处理不同。
- 第四种方案是 ES6 提出的方案,使用 importexport 的形式来导入导出模块。这种方案和上面三种方案都不同。参考 61

CommonJs和ES6模块化区别

- 加载
- 输出
- 导入
- this 指向

AMD 和 CMD 规范区别

它们之间的主要区别有两个方面。
(1)第一个方面是在模块定义时对依赖的处理不同。AMD 推崇依赖前置,在定义模块的时候就要声明其依赖的模块。而 CMD 推崇就近依赖,只有在用到某个模块的时候再去require。    
(2)第二个方面是对依赖模块的执行时机处理不同。
    首先 AMD 和 CMD 对于模块的加载方式都是异步加载。不过它们的区别在于模块的执行时机,AMD 在依赖模块加载完成后就直接执行依赖模块,依赖模块的执行顺序和我们书写的顺序不一定一致。
    而 CMD 在依赖模块加载完成后并不执行,只是下载而已,等到所有的依赖模块都加载好后,进入回调函数逻辑,遇到 require 语句的时候才执行对应的模块,这样模块的执行顺序就和我们书写的顺序保持一致了。

ES6 模块区别

  1. CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
  2. ES6 模块的运行机制与 CommonJS 不一样。遇到模块加载命令 import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
  3. this 的指向不同
  4. CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。CommonJS 模块就是对象,即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。

模块加载器实现

事件

事件循环

  • node10之后

    • 与浏览器事件循环一致
  • node10之前

    • 六大宏任务

      script 脚本的执行
      setTimeout 
      setInterval
      setImmediate
      I/O 操作
      UI 渲染
      
    • 微任务

事件机制

  • 事件代理/委托

    • 冒泡

      阻止冒泡:event.stopPropagation() 或者 ie 下的方法 event.cancelBubble = true;
      
    • 捕获

自定义事件

- new Event
- new customEvent
- document.createEvent('CustomEvent')+initEvent()

事件监听

- addEventListener

事件触发

- dispatchEvent

延迟加载

编程

手撕 JS

  • 节流

  • 防抖

  • Promise

  • ajax

  • this

    - call
    - apply
    - bind
    
  • Array

    - filter
    - flat
    - map
    - reduve
    
  • Object

    - new
    - create
    - instanceof
    - assign
    

深拷贝

  • 递归循环

  • 假深拷贝

    • JSON 序列化

      缺陷
        1. 时间对象 => 时间字符串
        2. RegExp、Error对象 => 空 {}
        3. function、undefined => 丢失
        4. NaN、Infinity、-Infinity => null
        5. 对象是由构造函数生成 => 丢弃对象的 constructor
        6. 无法对象自引用 => 报错
      
    • Object.assign()

浮点数千位数

// 方法一
function format(number) {
  return number && number.replace(/(?!^)(?=(\d{3})+\.)/g, ",");
}
// 方法二
function format1(number) {
  return Intl.NumberFormat().format(number)
}
// 方法三
function format2(number) {
  return number.toLocaleString('en')
}

精度问题

字符串解析编译

- eval
- new Function
- setTimeOut
- setInterval

1000000个数据的解决办法

我们需要思考的问题:该处理是否必须同步完成?数据是否必须按顺序完成?
解决办法:

(1)将数据分页,利用分页的原理,每次服务器端只返回一定数目的数据,浏览器每次只对一部分进行加载。
(2)使用懒加载的方法,每次加载一部分数据,其余数据当需要使用时再去加载。
(3)使用数组分块技术,基本思路是为要处理的项目创建一个队列,然后设置定时器每过一段时间取出一部分数据,然后再使用定时器取出下一个要处理的项目进行处理,接着再设置另一个定时器。

查找一篇英文文章中出现频率最高的单词

四位随机数

简单性能

代码

1.使用位运算代替一些简单的四则运算。
2.避免使用过深的嵌套循环。
3.不要使用未定义的变量。
4.当需要多次访问数组长度时,可以用变量保存起来,避免每次都会去进行属性查找。

移动端点击延迟

移动端点击有 300ms 的延迟是因为移动端会有双击缩放的这个操作,因此浏览器在 click 之后要等待 300ms,看用户有没有下一次点击,来判断这次操作是不是双击。还可能会造成点击穿透问题。
有三种解决办法:

1. 通过 meta 标签禁用网页的缩放。
2. 通过 meta 标签将网页的 viewport 设置为 ideal viewport。
3. 调用一些 js 库,比如 FastClick

检测浏览器版本

  • 检测 window.navigator.userAgent 的值,但这种方式很不可靠,因为 userAgent 可以被改写,并且早期的浏览器如 ie,会通过伪装自己的 userAgent 的值为 Mozilla 来躲过服务器的检测。
  • 功能检测,根据每个浏览器独有的特性来进行判断,如 ie 下独有的 ActiveXObject。

V8垃圾回收机制

【变量、作用域与内存】-大大的红宝书(四)

- v8 的垃圾回收机制基于分代回收机制,这个机制又基于世代假说,这个假说有两个特点,一是新生的对象容易早死,另一个是不死的对象会活得更久。基于这个假说,v8 引擎将内存分为了新生代和老生代。

- 新创建的对象或者只经历过一次的垃圾回收的对象被称为新生代。经历过多次垃圾回收的对象被称为老生代。

- 新生代被分为 FromTo 两个空间,To 一般是闲置的。当 From 空间满了的时候会执行 Scavenge 算法进行垃圾回收。当我们执行垃圾回收算法的时候应用逻辑将会停止,等垃圾回收结束后再继续执行。
  这个算法分为三步:
  (1)首先检查 From 空间的存活对象,如果对象存活则判断对象是否满足晋升到老生代的条件,如果满足条件则晋升到老生代。如果不满足条件则移动 To 空间。
  (2)如果对象不存活,则释放对象的空间。
  (3)最后将 From 空间和 To 空间角色进行交换。

- 新生代对象晋升到老生代有两个条件:
  (1)第一个是判断是对象否已经经过一次 Scavenge 回收。若经历过,则将对象从 From 空间复制到老生代中;若没有经历,则复制到 To 空间。
  (2)第二个是 To 空间的内存使用占比是否超过限制。当对象从 From 空间复制到 To 空间时,若 To 空间使用超过 25%,则对象直接晋升到老生代中。设置 25% 的原因主要是因为算法结束后,两个空间结束后会交换位置,如果 To 空间的内存太小,会影响后续的内存分配。

引用计数法

标记清除算法

- 标记阶段
- 清除阶段

常见内存泄漏

1. 意外的全局变量
2. 被遗忘的计时器或回调函数
3. 脱离 DOM 的引用
4. 闭包(低版本 IE )

node 寻址

  1. 如果 X 是内置模块(比如 require('http'))

    1. 返回该模块。
    2. 不再继续执行。
    
  2. 如果 X 以 "./" 或者 "/" 或者 "../" 开头

    1. 根据 X 所在的父模块,确定 X 的绝对路径。
    2. 将 X 当成文件,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。X、 X.js、X.json、X.node
    3. 将 X 当成目录,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。
    
  3. 如果 X 不带路径

    1. 根据 X 所在的父模块,确定 X 可能的安装目录。
    2. 依次在每个目录中,将 X 当成文件名或目录名加载。
    
  4. 抛出 "not found"

设计模式

JavaScript 中常见设计模式整理

DOM 操作

documen.write 和 innerHTML 区别

- document.write 的内容会代替整个文档内容,会重写整个页面。
- innerHTML 的内容只是替代指定元素的内容,只会重写页面中的部分内容

节点操作

  • 创建

    createDocumentFragment(node);
    createElement(node);
    createTextNode(text);
    
  • 添删改插

    appendChild(node)
    removeChild(node)
    replaceChild(new,old)
    insertBefore(new,old)
    
  • 查找

    getElementById();
    getElementsByName();
    getElementsByTagName();
    getElementsByClassName();
    querySelector();
    querySelectorAll();
    
  • 属性操作

    getAttribute(key);
    setAttribute(key, value);
    hasAttribute(key);
    removeAttribute(key);
    

虚拟 DOM

- 优缺点
- 比较 DOM 树差异
- 转为真实 DOM

跨域

原因

解决

1.通过 jsonp 跨域
2.document.domain + iframe 跨域
3.location.hash + iframe
4.window.name + iframe 跨域
5.postMessage 跨域
6.跨域资源共享(CORS)
7.nginx 代理跨域
8.nodejs 中间件代理跨域
9.WebSocket 协议跨域

Ajax

它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。

创建

1. 创建 XMLHttpRequest 对象,也就是创建一个异步调用对象
2. 创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息
3. 设置响应 HTTP 请求状态变化的函数
4. 发送 HTTP 请求
5. 获取异步调用返回的数据
6. 使用 JavaScript 和 DOM 实现局部刷新

状态码

  • (0) 未初始化

    此阶段确认XMLHttpRequest对象是否创建。
    值为0表示对象已经存在。
    
  • (1)载入

    已调用send()方法,正在发送请求
    值为1表示正在向服务端发送请求。 
    
  • (2)载入完成

    send()方法执行完成,接收服务器端的响应数据。
    值为2表示已经接收完全部响应数据。 
    
  • (3)交互

    此阶段解析接收到的服务器端响应数据。
    状态3表示正在解析数据。 
    
  • (4)完成

    解析已经完成。
    值为4表示数据解析完毕。
    

整个XMLHttpRequest对象的生命周期应该包含如下阶段: 【 创建-初始化请求0-发送请求1-接收数据2-解析数据3-完成4 】

正则表达式

ES6

常见方法

  • 数组

    数组和字符串的转换方法:toString() toLocalString()、join() 其中 join() 方法可以指定转换为字符串时的分隔符。
    数组尾部操作的方法 pop() 和 push(),push 方法可以传入多个参数。
    数组首部操作的方法 shift() 和 unshift() 重排序的方法 reverse() 和 sort(),sort() 方法可以传入一个函数来进行比较,传入前后两个值,如果返回值为正数,则交换两个参数的位置。
    数组连接的方法 concat() ,返回的是拼接好的数组,不影响原数组。
    数组截取办法 slice(),用于截取数组中的一部分返回,不影响原数组。
    数组插入方法 splice(),影响原数组查找特定项的索引的方法,indexOf() 和 lastIndexOf() 迭代方法 every()、some()、filter()、map() 和 forEach() 方法
    数组归并方法 reduce() 和 reduceRight() 方法
    fill 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。
    

常见属性

JS 常见概念

继承

【继承】-大大的红宝书

  • 原型

    p.__proto__
    p.constructor.prototype
    Object.getPrototypeOf(p)
    
  • 原型链

  • 创建对象

    • ES6: class 类

    • ES6 前模拟类

      工厂模式
        工厂模式的主要工作原理是用函数来封装创建对象的细节,从而通过调用函数来达到复用的目的。但是它有一个很大的问题就是创建出来的对象无法和某个类型联系起来,它只是简单的封装了复用代码,而没有建立起对象和类型间的关系。
      
      构造函数模式
      
      盗用构造函数
        大致基本思路为:在子类构造函数中调用父类构造函数。毕竟函数就是特定上下文中执行代码的简单对象,所以可以使用 apply () 和 call() 方法以新创建的对象为上下文执行构造函数。
        盗用构造函数基本上虽说解决了原型链继承的引用类型的缺陷,但也不能单独使用。
      
      组合继承
        使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性。这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性。
      
      原型式继承
        因为每一个函数都有一个 prototype 属性,这个属性是一个对象,它包含了通过构造函数创建的所有实例都能共享的属性和方法。因此我们可以使用原型对象来添加公用属性和方法,从而实现代码的复用。
        这种方式相对于构造函数模式来说,解决了函数对象的复用问题。但是这种模式也存在一些问题,一个是没有办法通过传入参数来初始化值,另一个是如果存在一个引用类型如 Array 这样的值,那么所有的实例将共享一个对象,一个实例对引用类型值的改变会影响所有的实例。
      
      寄生式继承
        基本思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。
        寄生式继承同样适合主要关注对象,而不在乎类型的构造函数的场景。Object.create() 函数不是寄生式继承所必需的,任何返回对象的函数都可以在这里使用。
      
      寄生式组合继承
        寄生式组合继承通过盗用结构函数继承属性,且使用混合式原型链继承方法。
        基本思路:使用寄生式继承来继承父类原型,将返回的新对象赋值给子类原型。
      

作用域

【变量、作用域与内存】-大大的红宝书(四)

  • 执行上下文

  • 变量提升

  • let/const/var

  • 作用域链

  • this

    - 隐式更改
      常见情况
        严格模式
        非严格模式
      箭头函数
    
    - 显式更改
      call/apply/bind
        (手撕)
        (区别)
    

闭包

概念及实现
    闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。

闭包有两个常用的用途。
    1.闭包的第一个用途是使我们在函数外部能够访问到函数内部的变量。通过使用闭包,我们可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。
    2.函数的另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。

其实闭包的本质就是作用域链的一个特殊的应用,只要了解了作用域链的创建过程,就能够理解闭包的实现原理。

- 内存泄漏排查
  chrome开发者工具
    Performance
    memory

异步

  • 异步发展史

  • Promise

    理解
    静态方法的实现
    
  • async

    • 与promise的区别

hasOwnProperty

所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性,和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。

JSON

JSON 是一种基于文本的轻量级的数据交换格式。它可以被任何的编程语言读取和作为数据格式来传递。

在项目开发中,我们使用 JSON 作为前后端数据交换的方式。在前端我们通过将一个符合 JSON 格式的数据结构序列化为 JSON 字符串,然后将它传递到后端,后端通过 JSON 格式的字符串解析后生成对应的数据结构,以此来实现前后端数据的一个传递。

因为 JSON 的语法是基于 js 的,因此很容易将 JSON 和 js 中的对象弄混,但是我们应该注意的是 JSON 和 js 中的对象不是一回事,JSON 中对象格式更加严格,比如说在 JSON 中属性值不能为函数,不能出现 NaN 这样的属性值等,因此大多数的 js 对象是不符合 JSON 对象的格式的。

在 js 中提供了两个函数来实现 js 数据结构和 JSON 格式的转换处理。
  JSON.stringify 函数,通过传入一个符合 JSON 格式的数据结构,将其转换为一个 JSON 字符串。如果传入的数据结构不符合 JSON 格式,那么在序列化的时候会对这些值进行对应的特殊处理,使其符合规范。在前端向后端发送数据时,我们可以调用这个函数将数据对象转化为 JSON 格式的字符串。
  JSON.parse() 函数,这个函数用来将 JSON 格式的字符串转换为一个 js 数据结构,如果传入的字符串不是标准的 JSON 格式的字符串的话,将会抛出错误。当我们从后端接收到 JSON 格式的字符串时,我们可以通过这个方法来将其解析为一个 js 数据结构,以此来进行数据的访问。

Object.definePropertype() 与 Proxy

延迟加载

- 放入底部
- defer
- async
- 动态创建 DOM
- setTimeout 延迟

类数组对象

  • 概念

    一个拥有 length 属性和若干索引属性的对象就可以被称为类数组对象,类数组对象和数组类似,但是不能调用数组的方法。
    常见的类数组对象有 arguments 和 DOM 方法的返回结果,还有一个函数也可以被看作是类数组对象,因为它含有 length 属性值,代表可接收的参数个数。
    
  • 转换

    Array.prototype.slice.call(arrayLike);
    Array.prototype.splice.call(arrayLike, 0);
    Array.prototype.concat.apply([], arrayLike);
    Array.from(arrayLike);
    [...arrayLike]
    

Polyfill

Polyfill 指的是用于实现浏览器并不支持的原生 API 的代码。

编码

  • escape,encodeURL,encodeURLComponent

    encodeURI 是对整个 URI 进行转义,将 URI 中的非法字符转换为合法字符,所以对于一些在 URI 中有特殊意义的字符不会进行转义。
    encodeURIComponent 是对 URI 的组成部分进行转义,所以一些特殊字符也会得到转义。
    escapeencodeURI 的作用相同,不过它们对于 unicode 编码为 0xff 之外字符的时候会有区别,escape 是直接在字符的 unicode 编码前加上 %u,而 encodeURI 首先会将字符转换为 UTF-8 的格式,再在每个字节前加上 %。
    
  • Unicode 与 UTF-8

    Unicode 是一种字符集合,现在可容纳 100 多万个字符。每个字符对应一个不同的 Unicode 编码,它只规定了符号的二进制代码,却没有规定这个二进制代码在计算机中如何编码传输。
    UTF-8 是一种对 Unicode 的编码方式,它是一种变长的编码方式,可以用 1~4 个字节来表示一个字符。
    

    Unicode 是一本字典,UTF-8 是怎么样使用这个字典。

常见问题


image.png

点这点这✨
二本获得阿里实习 offer 经历-宝藏篇(下)