Advertisement

2022大厂前端面试题手册

阅读量:

HTML、CSS、浏览器 相关:

1. 网络中使用最多的图片格式有哪些

在这些常见的图像文件格式中(如JPEG、GIF、PNG),JPEG是最受欢迎的;在将文件以JPEG格式存储于Photoshop(PS)中时(或When storing files in JPEG format within Photoshop),可以实现最大程度的压缩。

2. 请简述 CSS 盒子模型

CSS盒子从外到内的结构分为四个层次结构:外边距(margin)、边框(border)、内边距(padding)以及内容区域(content)。在默认设置下,默认状态下宽度与高度属性仅定义为内容区域的宽度与高度参数值。

盒子真正的宽应该是:内容宽度+左右填充+左右边距+左右边框

盒子真正的高应该是:内容高度+上下填充+上下边距+上下边框

3. 视频/音频标签的使用

视频:

复制代码
    <video src=""></video>

视频标签属性:

  • src 用于 playing 的 视频 地址
  • width 和 height 设置的操作 与 img 标签的一致
  • 决定 是否 启用 自动 播放 功能
  • 设置 可选 参数 来决定 是否 显示 控制 条
  • 在 未 开始 播放 前 会 展示 展位 图片
  • 确保 循环 选项 的 状态 是 正确 的
  • 设置 autoplay 后, preloaded属性会被忽略.
  • muted 是 静音 操作 模式.

音频: 音频属性和视频属性差不多,不过宽高和 poster 属性不能用

复制代码
    <audio> 
    	<source src="" type=""> 
    </audio>

4. HTML5新增的内容有哪些

  • 新增语义化标签
  • 新增表单类型
  • 表单元素
  • 表单属性
  • 表单事件
  • 多媒体标签

5. HTML5新增的语义化标签有哪些

语义化标签优点:1. 提升可访问性 2. SEO 3. 结构清晰,利于维护

  • 页面顶部
  • 页面主体内容
  • 页面底部
  • 导航栏
  • 侧边栏
  • 加载一段独立内容
  • section相当于 div
  • 图的一个独立部分(上图下文)
  • 图的部分标题为... figcaption...
  • 标题组合标签为hgroup...
  • 高亮显示某些部分mark...
  • 对话框部分需配合open属性加载dialog...
  • 插件相关的embed标记...
  • 视频正在加载中video...
  • 音频文件已支持ogg、mp3、wav格式audio...

6. CSS3 新增的特性

边框:

  • border-radios 为border元素添加圆角边框
  • border-shadow:给框添加阴影(横向偏移量, 纵向偏移量, 模糊半径值, 阴影宽度和高度, 阴影颜色参数, (inset, outset) 内部/外部阴影)
  • border-image:定义边框图像的路径和样式
  • border-image-source 边框图片的路径
  • border-image-slice 图片边框向内偏移
  • border-image-width 边框图像区域的宽度
  • border-image-outset 边框图像超出边界的部分
  • border-image-repeat 图像铺砌方式(repeat: 平铺; round: 铺满; stretch: 拉伸)

背景:

  • background-size 背景图片尺寸
  • background-origin决定了 background-position 属性的位置方式
  • background-clip 决定了绘制区域(padding-box, border-box, content-box)

渐变:

  • linear-gradient() 线性渐变
  • radial-gradient() 径向渐变

文本效果:

  • 单词截断设置决定了在文本过长时如何处理超出容器的部分。
    • 允许将过长的内容自动分配到多行以确保完整显示。
    • 控制当文本内容超出容器时的显示策略。
    • 文字阴影效果由四个参数控制——水平偏移量、垂直偏移量、模糊半径和阴影色调。

转换:

  • transform 适用于 二维和三维转换操作
  • transform 可实现旋转、缩放、平移和倾斜等几何变换
  • transform-origin 参数允许指定转换基准点位置
  • transform-style 属性定义嵌套元素在三维空间中的呈现方式

2D 转换方法

  • rotate around the origin by, translate (x, y) to specify displacement in 2D space, and scale by a factor of n.*

3D 转换方法:

  • perspective(n)为 3D 转换 translate rotate scale

过渡:

  • transition-parameter 定义了过渡过程所需的属性项
  • transition-duration 表示完成过渡过程所需的时间
  • transition-timing-function 指定了切换过程的速度设置
  • transition-delay 设置了切换过程的起始时间偏移值

动画:animation

  • animation-name 用@keyframes 标识动画名称
  • animation-duration 表示动画完成所需的时间段
  • animation-timing-function 描述动画在完整周期中的运动模式
  • animation-delay 表示动画启动前的静止时长
  • animation-iteration-count 表示动画播放的总次数
  • animation-direction 用于指示是否按正反方向轮流播放动画

7. 清除浮动的方式有哪些?请说出各自的优点

高度塌陷:当所有子元素发生浮动时,并且父元素未预先设定好高度,则此时该父容器将出现高度塌陷现象

给父元素单独定义高度
优点:快速简单,代码少 缺点:无法进行响应式布局

父级定义 overflow: hidden;zoom: 1(仅适用于 IE6 的兼容性配置)
优点:简洁高效且代码量少,并具有较好的兼容性
缺点:超出显示区域的部分会被隐藏起来,在布局过程中需要特别注意

在浮动元素后添加一个空标签,并设置其属性为clear: both; height: 0px; overflow: hidden。优点包括简洁高效且代码量小以及兼容性较好;缺点在于增加了不必要的空标签条目,在页面优化方面存在不足

父级设置为overflow: auto
优点主要有三点:
一是结构简洁;
二是代码量较少;
三是兼容性较好。
需要注意的是,在内部高度超过其parent div时会生成水平滚动条。

万能清除法:

给塌陷的元素添加伪对象

复制代码
    .father:after{ 
    Content:“随便写”; 
    Clear:both; 
    display:block; 
    Height:0; 
    Overflow:hidden; 
    Visibility:hidden 
    }

优点:写法固定,兼容性高
缺点:代码多

8. 定位的属性值有何区别

  1. position属性包含四个可能的取值:relative、absolute、fixed和static。
  2. 在相对定位关系中(relative positioning),元素不会脱离文档流,在其自身的坐标系内进行布局。
  3. 绝对定位(absolute positioning)下,元素会脱离文档流并基于其父容器的位置进行布局。
  4. 固定(或称为块级)定位(fixed positioning)使元素脱离文档流并以浏览器窗口为基准进行布局。
  5. 在标准(default)状态下,默认情况下,“static”属性会被设置为true,在标准状态下,默认情况下,“static”属性会被设置为true,在标准状态下,默认情况下,“static”属性会被设置为true。
  6. default状态下,默认情况下,“static”属性会被设置为true,在标准状态下,默认情况下,“static”属性会被设置为true。
  7. default状态下,默认情况下,“static”属性会被设置为true。

9. 子元素如何在父元素中居中

水平居中:

  1. 父级元素宽度固定情况下,默认实现 margin auto 设置
  2. 父级设定 text-align: center 属性后,默认采用 inline-block 属性配置

水平垂直居中:

  1. 子元素基于父容器实现绝对定位,在其top和left方向上分别指定50%的比例值,并对margin-top与margin-left属性扣除各自宽度与高度的一半数值
  2. 子容器基于父容器实现绝对定位后,在其上下左右四边全部设为零值并应用水平垂直居中的样式
  3. 父容器指定display属性及vertical-align属性以实现表格单元格垂直居中显示效果
  4. 子容器基于自身进行相对定位并在其top与left方向上分别设定50%的比例值随后执行平移变换操作
  5. 子容器基于父容器实现相对定位并在其top与left方向上分别设定50%的比例值同时对其进行平移变换操作
  6. 父容器指定弹性布局并应用水平垂直居中的排版策略

10. border-box 与 content-box 的区别

content-box 标准盒模型的宽度未涉及padding和border;border-box 怪异盒模型的宽度涵盖padding和border

11. 元素垂直居中

  1. 调整子元素与父容器的高度一致
  2. 将子元素定位为行内块,并对其垂直对齐应用中点位置
  3. 当已知父容器的高度时,在其中添加一个相对定位的子元素,并对其应用 translateY(-50%)的变换
  4. 当无法确定父容器的高度时,在其内部添加一个自定义高度的盒子作为参考,并将其顶部调整至父容器的一半位置,并对其进行 translateY(-50%)的变换
  5. 创建一个隐藏节点用于占位,并将其高度设置为剩余可用空间的一半
  6. 将父容器设置为显示表格布局,并在其内部添加表单元格级别的孩子元素;同时对这些孩子进行垂直对齐处理
  7. 向父容器中追加一个虚拟DOM节点
  8. 使用弹性盒子模型作为 flex 容器并为其分配 flex-grow 属性;同时将所有孩子 flex: align-self: center 设置为居中显示

12. 如何让 chrome 浏览器显示小于 12px 的文字

最初添加了谷歌私有属性 -webkit-text-size-adjust: none , 现在应用了变换缩放 -webkit-transform: scale()

常见的CSS 选择器有哪些?哪些属性可以继承?其优先级是如何计算的?此外,请列举一下CSS3中新增的主要伪类都有哪些。

CSS2 直接元素定位法:直接元素定位法(element selector)、ID定位法(ID selector)、父元素定位法(parent selector)、类名定位法(class selector)、通配符定位法(wildcard selector)、子元素定位法(descendant selector)
CSS2 随机属性值匹配:a:link / a:visited / a:hover / a:active
CSS3 空格>前后兄弟>~通用选型:空格>前后兄弟>查找后面所有子元素

结构伪类选择器

获取第n个 nth-in排(n) 获取同一类别的第n个 nth-in同一类 【获取

属性选择器:基于标签属性进行查找 [attr=value]的形式
: root 用于查找HTML标签及其子节点
: empty 则专门用于查找空标签

该选择器 用于表单元素的选择。
当设置为enabled时 查找允许的标签。
当设置为disabled时 查找禁止使用的标签。
当设置为checked时 查找被选中的标签。

伪元素选择器
: selection 设置选中文本内容进行高亮显示(仅适用于背景色和文本颜色设置)

否定伪类选择器 not()

语言伪类选择器 lang(取值)

优先级(权重)

元素选择器 1

伪元素选择器 1

class 选择器 10

伪类选择器 10

属性选择器 10

Id 选择器 100

内联样式的权重 1000

包含选择器权重为权重之和

继承样式权重为 0

哪些属性可被继承

哪些属性可被继承

哪些属性可被继承

哪些属性可被继承

哪些属性可被继承

14. 网页中有大量图片加载很慢 你有什么办法进行优化?

  1. 实现图片懒加载功能,在不可见的图像区域触发滚动条事件以获取图像位置信息,并比较该位置与浏览器顶端的距离以及页面整体高度
  2. 通过预加载技术优化页面加载流程
  3. 使用 CSSsprite 或 svgsprite 技术

15. 行内元素/块级元素有哪些?

行内元素:相邻的行内元素将排列在同一行,在设置宽高无效的情况下 span 将不会独占一行
块级元素:当设置宽高等属性时 div 将单独占用一行,并支持相关属性
可变元素:该 HTML 元素将根据上下文确定是块类型还是内联类型

段落:一级标题至六级标题;行内:一个行分隔符;样式:加粗文字;图片;输入字段;选择器;段落;子类型无序列表;子类型有序列表;表格;地址;引文格式文本块;方向键(从菜单中)

16. 浏览器的标准模式和怪异模式区别?

标准模式 :浏览器遵循 W3C 标准遵循执行代码
怪异模式 :浏览器采用不同的方式执行代码 由于各浏览器对执行方式有不同的处理

区别
采用怪异模式时,默认将盒模型定义为怪异盒子模型;与此相对应的是,在标准模式下的box model则被指定为标准盒子模型。针对行内元素以及表格单元格元素而言,在标准配置中 images 的 vertical-align属性 default 值设置为 baseline;而当采用怪异模式时,则将 tables单元格内的 images element 的 vertical-align属性 default 设置为 bottom;这样一来,在这些图像底部会多出大约几像素的空间间隔

在CSS中对字体属性的继承性是默认设置为可遗传的,在特殊模式下(如怪异模式),表单元格中的字体属性无法从其父级或其他相关容器继承。特别地,在这种情况下通常涉及字体大小设置的问题。

在内联元素的标准模式下,默认情况下无法通过非替换单线文字元组件独立设置其大写样式,在奇异模式中,默认情况下宽度与高度的变化会相应影响文本内容的显示大小。

元素的百分比高度,在使用百分比高度的情况下,在标准模式中其高度取决于内容的变化情况;在异常或混乱的状态下,则能得到准确的应用。

在标准处理流程下,默认情况下overflow设置为 visible;但在特殊模式下(如怪异模式),该行为会被视为扩展box处理,并不会裁剪溢出的内容,元素框会自动适应并包含所有溢出的内容

17. margin 和 padding 在什么场合下使用

外侧间距是指元素边缘至相邻边界区域的距离;内侧间距则是指元素内部边缘至内部内容区域的距离。

为了在外边增加空白空间而使用 margin, 为了在内边增加空白空间而使用 padding

18. 弹性盒子布局属性有那些请简述?

  • flex-direction 表示弹性容器中子元素沿主要方向的排布情况。
  • flex-wrap 控制当弹性盒子里的子元素超过父容器边界时是否会换行。
  • flex-flow 是 flex-direction 和 flex-wrap 的简写形式。
  • align-item 控制弹性盒子内部元素沿侧边的对齐策略。
  • align-content 设置行方向或列方向的整体对齐模式。
  • justify-content 控制弹性盒子里各项沿主要方向的排布策略。

19. 怎么实现标签的禁用

添加 disabled 属性

20. Flex 布局原理

就是通过给父盒子添加 flex 属性,来控制子盒子的位置和排列方式

21. px,rem,em 的区别

  • px 是一种绝对长度单位。
    • 它基于显示器屏幕分辨率。
    • em 的具体数值并非固定。
    • 它会继承父级元素的字体大小(参考物是父元素 font-size)。
    • 所有的字体都是相对于父元素决定因素。
    • rem 是相对于 html 根元素 font-size 的。
    • 1em 等于 1rem 等于 16px,在 body 中设置 font-size 属性为 62.5%,这样直接就是原来的 px 数值除以 10 加上 em 就可以。

22. 网页的三层结构有哪些

  • 结构(HTML 或 XHTML 标记语言)
  • 表现(CSS 样式表)
  • 行为(JavaScript)

25. 请简述媒体查询

媒体查询通过新增 media 属性实现了对不同媒体类型的自适应样式配置。

26. rem 缺点

比如,在小说网站上运行时,在使用移动设备屏幕尺寸较小时采用rem缩放机制时,默认文字会相应变小;这会使得阅读体验异常刺眼。

27. 三栏布局方式两边固定中间自适应

  1. margin 负值法:左右两边分别使用绝对定位固定在页面两侧边缘,并将中间区域通过左右 margin撑开空间。
  2. 自身浮动法:左边框左移、右边框右移后,在右侧留出足够空间放置居中部分。
  3. 绝对定位法:在页面左侧和右侧分别设置左边框和右边框作为容器,并在中间部分应用左右 margin撑开距离。
  4. flex 左右固定宽 中间 flex:1:使用 flexbox 铺排,在左右两边分别设置固定宽度,并将中间区域分配给 flex-grow 属性。
  5. 网格布局:基于网格系统设计实现页面分区。
  6. table 布局:通过表格结构实现信息展示与排版设计。

28. !DOCTYPE 作用

声明文档类型

29. 说一下 HTML5 drag api

  • dragstart事件发生在被拖放元素开始拖放时,并涉及被拖放元素作为主体。
  • dragend事件发生于整个拖放操作结束时,并与被拖放元素相关联。
  • dragenter事件会在目标区域接收到来自其他区域的拖放动作时触发。
  • dragleave事件会在目标区域失去接收到的拖放动作时触发。
  • drop事件会在目标区域完全接收并处理来自其他区域的物品移动请求时触发。
  • dragover事件会在目标区域内接收到来自其他区域的动作并持续一段时间后触发。
  • darg事件发生于正在移动的被拖放元素,并与该动作直接相关联。

30. 对 HTML 语义化标签的理解

HTML5语义化标签被定义为正确的标签包含了正确的内容,并且具有良好的结构,并且易于阅读。例如nav标签表示导航条, 以及其他常见类型如article, header以及footer等也属于这一范畴。

31. Web性能优化

优化流量管理:通过资源整合与压缩技术减少HTTP请求数量,并采用minify/Gzip压缩、webP格式以及lazyLoad机制来进一步降低带宽消耗与响应时间。提升访问速度:引入预解析DNS加速技术以减少域名数量,并通过多线程并行加载内容实现更快的初始页面加载速度;同时结合CDN网络分发策略以确保快速响应能力。

缓存机制:HTTP协议用于缓存请求,并实现离线存储功能。具体包括以下内容:1. 离线存储manifest文件;2. 离线存储数据至localStorage中。在渲染流程中,则包含以下步骤:1. JS/CSS优化以提升性能;2. 根据加载顺序进行资源编排;3. 实现服务器端渲染流程以减少客户端负担;4. 采用数据处理流水线技术提高效率。

32. 浏览器缓存机制

缓存主要分为两种类型:强式缓存与协商式缓存。依据响应的Header内容来确定强式缓存相关的字段主要有expires和Etag/If-None-Match。当同时包含cache-control和expires时,则以cache-control的优先级更高。协商式缓存相关的字段主要有Last-Modified/If-Modified-Since以及ETag/If-None-Match等

33. 浏览器输入网址到页面渲染全过程

  1. DN
  2. 解析TCP
  3. 建立连接
  4. 发送一个HTTP请求
  5. 服务器接收请求并响应
  6. HTTP报文的解析过程
  7. 显示页面内容
  8. 连接终止

34. 画一条 0.5px 的线

采用 meta viewport 的方 式

复制代码
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

采用 border-image 的方 式 采用 transform: scale() 的方式

35. 关于 JS 动画和 CSS3 动画的差异性

渲染线程主要分为两大类:一个是主线程(Main Thread),另一个是复合器线程(Compositing Thread)。当CSS动画仅影响图形的变换(Transform)和平移(Opacity)时,则在此处完成;与此不同的是,在主线程中运行完成后会触发复合器线程进行后续处理。需要注意的是,在变换(Transform)和平移(Opacity)发生变化时并不会导致布局(Layout)或画面(Paint)的变化。

区别:

  • 功能范围方面,则JavaScript在实现上超过了CSS。
    • 在实现或重构难度上各有千秋的情况下,在性能优化方向上固定针对帧速较慢的低版本浏览器时段时(原意为:性能跳优方向固定针对帧速表现不好的低版本浏览器),通过自然降级机制确保兼容性。
    • 尽管CSS动画本身就具备事件驱动的支持特性。

36. 双边距重叠问题(外边距折叠)

多个连续(具有亲缘关系)普通流的块元素垂直方向 margin 会因存在多个相邻而发生重叠折叠。

当这两个相邻的外边距均为正值时,则其折叠结果为其两者之间的最大值。
若这两个相邻的外边距均为负值,则其折叠结果为其绝对值中的较大者。
当这两个相邻的外边距一个为正值、另一个为负值时,则其折叠结果为其总和。

37. 浮动清除

方法一:使用带 clear 属性的空元素在浮动元素后使用一个空元素如

复制代码
    <div class="clear"></div>,并在 CSS 中赋予.clear{clear:both;}属性

即可清理浮动。亦可使用

复制代码
    <br class="clear" />或<hr class="clear" />

来进行清理。

方法二:使用 CSS 的 overflow 属性

为了清除浮动效果,在容器中添加overflow: hiddenoverflow: auto可以有效去除浮出状态。此外,在IE6中还需通过hasLayout来触发相关效果,并可为父元素设置容器的宽度高度或调整zoom属性。

当设置overflow属性时,浮子元素重返父容器空间,使得父容器的高度得以提升,从而实现了浮子元素的移出效果

方法三:给浮动的元素的容器添加浮动

为具有嵌套浮动元素的容器增添浮窗属性即可消除内部相对漂移的问题;然而这样做会导致该容器(指上述情况)整体位置发生偏移;因此不建议采用此方法。

为具有嵌套浮动元素的容器增添浮窗属性即可消除内部相对漂移的问题;然而这样做会导致该容器(指上述情况)整体位置发生偏移;因此不建议采用此方法。

方法四:使用邻接元素处理

不做任何事情,在浮动元素之后添加 clear 属性的方法五:利用 CSS 的:after 伪素材

通过将after伪元素作为当前元素的后跟伪元素(注意此为特定类型)与IEhack技术结合(其中IEhack指的是hasLayout属性的检测),我们可以实现全浏览器兼容效果。其中IEhack指的是hasLayout属性的检测。为浮动容器添加class样式块,并在其后跟附加一个:after伪块以实现对末尾可见性不可见但能触发滚动的行为。通过在:after的位置插入不可见的块状内容来清除浮动效果。

38. CSS 选择器有哪些,优先级呢

当一个HTML元素同时应用了多种样式规则时(基于ID的属性筛选器、基于CSS类名的属性筛选器、基于HTML标签名的属性筛选器、用于匹配HTML中的空白元素节点的属性筛选器以及用于匹配CSS中未定义显示类型的虚拟元素节点的属性筛选器等),随后声明的样式规则会被前面声明的具体样式规则所覆盖;

不同类型的样式选单器其优先级排序则为:依次为id选单器、class选单器以及标签选单器;

当标签之间存在层级包含关系时,在这种情况下后裔元素会继承其父系元素的样式设定。当后裔元素明确指定了与其父系相同的样式设定时,在此情况下其父系所具有的相同样式的属性将被覆盖。此外,在这种情况下继承下来的样式的优先级较低,并且至少低于标签选择器

带有!important 标记的样式属性的优先级最高;

当源文件中样式的来源不同时,则其优先级顺序依次为:内联样式、内置样式、外部样式、用户自定义样式及系统默认样例

39. CSS 动画如何实现

生成动画序列必须依赖 animation 属性及其相关子属性。这些属性允许设置时间参数包括时长以及其它相关设置项。然而需要注意的是,这些设置仅影响视觉效果的某些基础特性而非全部细节,具体情况可参考通过@keyframes 规定各阶段动画流程及过渡效果的详细说明。具体实现方式可参考通过@keyframes 规定各阶段动画流程及过渡效果的详细说明,其中特别提到了如何定义不同时间段的小节部分以构建完整的 animations 序列。此外, transition 也可作为实现 animations 的另一种有效手段

transition 侧重于表现过渡效果,在元素的属性发生变化时所呈现的变化即为 transition 的一种表现形式。同一个元素能够通过两种不同的方式获取样式信息,在第二种方式中当某种变化发生(例如 hover)时才会切换到新的样式信息状态,从而导致出现 transition 动画效果。

40. 如何实现元素的垂直居中

  1. 父容器采用display: flex以及align-items: center的设置
  2. 该元素采用绝对定位方式,并设置top值为50%,同时通过 margin-top属性实现与容器边缘距离的具体计算
  3. 当无法确定具体高度时,默认采用transform: translateY(-50%)的方式进行动态尺寸调整
  4. 父容器采用table布局方式,并对其中的所有子元素实施vertical-align: center的居中显示处理

41. CSS3 中对溢出的处理

属性text-overflow设定了文本处理的方式以应对溢出情况。其值设定为'clip'时会截断显示内容;通过使用...符号将能够表示截断的部分;而指定字符串则会明确显示被剪裁的部分。

42. 对 CSS 的新属性有了解过的吗?

CSS3 的新特性中,在布局方面新增了 flex 布局,在选择器方面新增了

包括 first-of-type 和 nth-child 这类选择器,在盒模型方面增加了 box-sizing 来调整盒子模型,在动画效果上增添了几何动画(如 animation, 2D 和 3D 变换),在颜色系统中加入了透明度属性和 rbga 颜色格式,在字体样式上支持嵌入式字体样式以及设置阴影效果,并且还包括了媒体查询机制以实现跨设备自适应设计。

43. overflow 的原理

为了阐述这一解决方案的工作原理, 首先需要理解其基础架构中的核心概念, 其中一个块格式化区域是Web页面CSS视觉渲染的一部分. 这一区域主要负责块元素布局以及浮力交互机制的具体实现.

当一个元素配置了 overflow: visible属性,并且其 value 属性为可见时,则会生成一个 Bounding Floating Corner(BFCCorner)。在该 BFC 的 height 计算过程中(height calculation),其中在其 height 计算过程中包含的浮动子元素也被纳入考量。这表明,在该技术框架下(BFCTechnique),每个 BFC 内部仅包含单个浮动子元素。因此,在这种情况下(scenario),其 height 在此框架下不会发生收缩现象(contract phenomenon)。从而实现了消除这些浮动效果的目标(goal)。

44. CSS 定位

定点定位 fixed: 元素的位置基于浏览器窗口呈现固定位置状态无论浏览器窗口如何滚动都不会发生移动变化 fixed 定位确保元素不会因页面滚动而发生位置变动 固定定位的元素与其他任何层面上的元素可能会出现重叠情况

相对定位(relative positioning):如果对一个元素执行相对定位操作,则该元素将位于其所在的区域中。随后,在设置垂直和水平偏移量时(即指定相对于某个起点的纵向和横向位置),该元素将被放置在其起点的正上方、正下方、左侧或右侧的位置上。“相对于”的话可以用"relative to"来替代,并根据具体情况调整其位置。“在使用相对定位时”,无论是否发生移动操作,“其原始区域”这一块空间都会被保留下来。“因此”,当发生移动操作时,“该元素就会被其他框遮挡”。

绝对定位 absolute:The position of absolutely positioned elements relative to their most recently positioned parent element, if any. If an element has no previously positioned parent element, its position is relative to the <html> root.

sticky: 元素会先按普通文档流进行定位,并随后相对于该元素在其流中的 flow root (BFC) 和 containing block (最近的块级祖先元素)进行定位操作。随后, 元素的表现形式会在跨越特定阈值时转为相对定位, 超过阈值后则变为固定定位

Default positioning using static: default value. Without any positioning, elements appear in the normal flow (ignoring top, bottom, left, right or z-index properties).

inherit: 规定应该从父元素继承 position 属性的值。

Javascript 相关

1. Js 基本数据类型有哪些

字符串 String 数值 Number 布尔 boolean null undefined 对象 数组

2. Ajax 如何使用

一个完整的 AJAX 请求包括五个步骤:

  1. 生成一个XMLHTTPRequest对象。
  2. 通过open方法创建http请求,并指定请求地址。
    //通常会使用的open方法参数包括:方法类型(get/post),URL路径以及是否异步(true表示异步)
  3. 配置并发送数据至服务器端。
  4. 注册事件以处理服务器端返回的响应。
  5. 接收响应后及时更新页面状态。

3. 如何判断一个数据是 NaN

NaN 非数字,但是用 typeof 检测是 number 类型

基于 NaN 的定义, 我们可以通过 typeof 操作符确定变量是否为 number 类型, 并检查该值是否为 NaN.
其独特的性质是, 其与自身比较的结果始终为 false, 即 n 与自身的比较结果始终为 false.
借助 ES6 引入的 Object.is()函数来实现两个值相等性的检查, 这一方法能够有效区分不同类型的 NaN 值.

在if语句中进行判断时, 两者都会被当作假处理. 在if条件判断中, null会被当作假处理, 而undefined同样会被当作假处理. 当转换为数值类型时, null会被赋值为0, 而undefined会被赋值为NaN.

null意味着该变量被赋了一个空值。undefined是一个未赋值的变量定义。

5. 闭包是什么?有什么特性?对页面会有什么影响

我们可以将闭包视为一种嵌入在其外部函数体内的特殊结构。当一个内部函数在不依赖于其外部环境的情况下被调用时,从而形成闭包。

特点:

  1. 该函数嵌套调用自身。
  2. 该函数内部能够访问并使用外部定义的参数与变量。
  3. 这些参数与变量将被永久保留而不被垃圾回收机制清除。

使用:

  1. 获取该函数内部的变量;
  2. 这些变量的值始终保留在内存中,并且不会在外层函数调用后由系统自动清除。

优点:

  1. 变量长期驻扎在内存中;
  2. 避免全局变量的污染;
  3. 私有成员的存在 ;

缺点:会造成内存泄露

6. JS中常见的内存泄漏:

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

7. 事件委托是什么?如何确定事件源(Event.target 谁调用谁就 是事件源)

事件委托其本质是基于冒泡机制实现的。通过只需编写一个事件处理程序即可实现对同一类型所有事件的统一管理。

作为一种高效的实现手段,在JavaScript中对事件进行代理也是一项非常常见的做法。
它的主要作用是将原本应当绑定在子元素上的响应性事件转移至父元素上进行处理。
这一技术的核心依据在于DOM层级结构中发生的冒泡现象

8. 什么是事件冒泡?

一个事件触发后,会在子元素和父元素之间传播,这种传播分为三个阶段:

  1. 收集阶段(从 window 对象传递到目标节点(由外向内),该阶段不处理任何事件)
  2. 目标阶段,在此处触发
  3. 冒泡过程(从目标节点传递回 window 对象(由内向外)),通过这种机制确保内层需求得到充分处理

Cookie 通常意指一种薄脆的小饼干。考虑到其大小一般限定在约4KB范围内,在实际应用中还有其他重要用途。例如,在网络服务中,“记住密码”功能往往通过将一段用于鉴别用户身份的信息存储于 Cookie 中来实现这一需求。

这项技术属于HTML5新增功能。它并非革命性的创新。在IE 6浏览器时代就存在userData用于本地存储功能。出于兼容性考量,早期方案转向使用Flash技术。如今localStorage已成为主流技术,在几乎所有浏览器中均有支持。若网站目标用户涵盖IE6及以上版本,则推荐选用userData作为解决方案较为合适。

SessionStorage 和 LocalStorage 在接口设计上相似,但两者的持久化机制存在差异.对于熟悉前端技术的朋友而言,大家都知道"session"一词的具体含义.实际上, session意为"对话",而 SessionStorage 则是一个更为具体的概念.它仅能暂时存储当前会话中的部分数据信息,这些数据在页面刷新后依然保留在内存中.然而,一旦页面内容被重载或关闭,SessionStorage 中的所有存储内容都会被清除.

三者的异同

特性 数据的生命期 存放数据大小 与服务器端通信 易用性
Cookie 一般由服务器生成,可设置失效时间。如果在浏览器端生成 Cookie,默认是关闭浏览器后失效除非被清除,否则永久保存仅在当前会话下有效,关闭页面或浏览器后被清除 4K 左右 每次都会携带在 HTTP 头中,如果使用 cookie 保存过多数据会带来性能 需要程序员自己封装,源生的 Cookie 接口不友好
LocalStorage 永久保存在本地,可设置失效时间, 一般为 5MB 问题
SessionStorage 会话期间 一般为 5MB 仅在客户端(即浏览器)中保存,不参与和服务器的通信 源生接口可以接受,亦可再次封装来对 Object 和 Array 有更好的支持

10. ES6 新特性

const 和 let 用于变量声明(常量声明与变量声明),模板字符串用于字符串插值运算符(支持${}语法格式),箭头函数是一种非传统声明语法结构(不使用关键字),函数的参数默认值允许指定默认参数(简化显式传递),对象和数组解构提供了一种高效的数据解析方式(通过...操作符实现属性分离),for…of 循环用于遍历迭代器集合(基于object索引访问顺序),for…in 循环则用于访问对象属性枚举索引(包括继承链中的字段),ES6 中的类实现了面向对象编程的核心机制(通过类构造器功能实现)。

11. let 与 var 与 const 的区别

使用 var 关键词声明的变量会被分配到 window 对象中。相比之下,在 declare 语法(即 let 和 const)中声明的全局或块级作用域中的对象不会进行这样的绑定操作。值得注意的是,在 declare 语法中引入的新属性将被附加到对应的对象上,并且这种行为会对现有属性产生影响。此外,在同一个作用域内(例如函数或模块),使用 var 关键词可以定义与已有同名属性发生冲突的情况。

让和const声明属于块级作用域。当const被声明时必须进行赋值操作;不能使用null占位符;一旦声明,则无法更改其值;如果所声明的数据类型是复合型,则允许对其属性进行修改。

12. 数组方法有哪些请简述

  • 在末尾添加元素的方法是 arr.push() ,它会返回新数组的长度
    • arr.pop() 可用于从数组末尾移除一个元素 ,返回被移除的元素值
    • 使用 arr.shift() 可从前端移除第一个元素 ,并获得被移除的内容
    • arr.unshift() 在数组前端添加新元素 ,同时返回新数组长度
    • arr.splice(i,n) 方法允许从索引 i 开始删除接下来 n 个元素
    • 将两个或多个数组合并的操作由 arr.concat() 执行 ,并返回连接后的数组对象
    • arr.sort() 可对数组进行排序,默认按最左端数值排序而非直接按大小顺序排列
    • 将数组顺序反转的操作由 arr.reverse() 完成
    • 使用 slice(start,end) 方法可创建子数组 ,该子数组不包含索引 end 处的元素
    • 遍历所有数组元素的方法是 forEach ,即使带有 return 结构也不会影响原始数据
    • map 函数对输入数组中的每个元素执行特定操作 ,并生成新的结果集合
    • filter 方法筛选出符合条件的元组并构成新集合
    • str.split() 方法将字符串分解为字符序列,默认生成一个字符数组对象

13. json 如何新增/删除键值对

14. 什么是面向对象请简述

面向对象是一种概念性思维模式,在这一理念指导下,在这种模式下,则是指将功能等分配到不同的具体实体中进行管理。具体来说,在这种模式下,则是指将这些功能整合到特定的对象里,并使得各个具体操作能够由相应的对象独立完成;其核心在于将数据置于首位地位,并通过这种方式实现了对数据的高效管理;操作流程更加便捷的同时,则使得整个处理流程大大简化了处理流程。

在JavaScript中,并没有类的定义。然而,在每个普通功能内部都会存在一个 prototype 属性。这个 prototype 指向一个对象,在特定条件下(即当该功能被用作构造函数)时,则会发挥出与 class 类似的作用。

面向对象模型包含三个核心要素:信息隐藏(阻止访问对象的内部属性和方法实现细节,并提供公共接口供外部操作),代码复用性(通过继承机制实现功能共享),以及派生调用(允许引用变量指向子类实例或具体实现类型)。

15. 普通函数和构造函数的区别

构造函数本质上是一个普通的函数,在创建方式上与普通函数一致但通常采用首字母大写的命名习惯。
调用方法有所不同,在常规情况下直接调用普通函数即可;而构造函数则需使用关键字new加以触发。
在执行过程中会产生显著的不同:构造函数内部会生成新的对象即实例对象;而普通函数在常规调用下不会产生新的对象。
在方法体内this变量始终指向当前实例对象;而对于普通函数而言this变量则指向被调用的具体对象(若无特定指针绑定则默认指向window窗口)。
构造函数在运行后将自动返回所创建的对象即实例;而普通函数其返回值取决于具体的return语句配置。
值得注意的是构造函数的名字与其所属类名具有完全一致的关系。

16. 请简述原型/原型链/(原型)继承

什么是原型:
每个对象实例都具有自己的原型(prototype),也被称为原型对象(prototype object)。这个原型通过内建属性proto连接到其构造函数(constructor)所指代的目标类型(target type)。换句话说,“ proto: target_type”。
即任何一个对象都是通过其构造函数来生成并赋些建立起与目标类型之间的关联关系的。
并不是所有的对象都拥有 prototype属性。

什么是原型链?

原型链的基础就是依赖对象中proto_属性的关联关系,在不具备自身的属性时,则会通过不断获取构造函数的方式层层深入,在到达Object级别后就不再存在proto_属性了。由于proto_实际上是指向prototype的对象,在这种情况下我们只需关注这些构造函数本身即可。

每个构造函数均对应一个prototype object。这些prototype objects各自都持有指向其对应constructor的一个指针。每一个instance都持有指向其所属prototype object内部结构的引用。我们让prototype object (1)等于另一个prototype object的具体实现体(2),此时.prototype object (2)将持有指向prototype object (1) 的引用。接着我们再将prototype object (2)的具体实现体设为Prototype object (3),如此层层递进就构成了 instance 和 prototype 之间的链条关系。由此形成了instance与prototype间的关联网络

每个构造函数均有一个对应的 prototype 对象,在这种情况下,“prototype”的定义被明确化为一种独立于具体的实例类型而存在的结构体。每个 prototype 对象内部都会明确指定其所属的具体构造函数(即 constructor),而任何具体的实例对象都会在其属性中明确保留指向其父级 prototype 的内部指针 __proto__。如果将某个 prototype 对象赋值给另一个 instance 的 prototype,则该赋值后的 prototype 对象会在其属性中明确保留指向被赋值的那个 prototype 的内部指针 __proto__;而原来的那个 prototype 对象也会在其属性中明确保留指向其所属的具体 constructor(即 类型)的对象。如果这个被赋值的对象又是一个其他类型 instance 的 prototype,则这种 parent-child 的关联关系会继续延伸下去……最终就形成了从具体 instance 到其 parent、再到 grandparent 依此类推的一条 chain(链条)。这也被称为 prototype 链表或 prototype 链式继承,在 JavaScript 中这是一种主要实现继承的主要方法。基本思路就是利用 prototype 来让引用类型能够继承自其他引用类型的属性和方法。

通过使用 prototype 中的成员(属性或行为),它可以与与其相关联的对象共同拥有的特征进行共享。这实现了对自身属性或行为的传承,并我们称之为 prototype inheritance.

17. Promise 的理解

一、什么是 Promise?
大家普遍认为, Promise 作为一种解决方案, 它是实现可靠异步通信的一种方式. 与传统的方法相比, Promise 更加高效. 在语法结构上, promise 可以作为一个独立的对象进行引用和操作.

二、promise 有三种状态:
The initial state, also referred to as the pending state, is also known as the waiting state; similarly, the fulfilled state is another significant status that represents success, while the rejected state is designated for indicating failure. Once its state changes, it will no longer revert back. Upon creating a promise instance, it will immediately execute.

三、Promise 的两个特点

  1. Promise 对象的状态能够保持不受外部因素的干扰
  2. 当 Promise 的状态发生变化时,其后续的状态将不再逆转,并且无论何时查询该对象的状态都能获得最新结果。

四、Promise 的三个缺点

  1. Promise一旦被创建就会立即执行而无法终止
  2. 若未指定回调函数则Promise内部发生之错误不会对外产生影响
  3. 当处于等待状态时我们无法得知当前进度是初始状态还是接近完成状态

18. 我们用 Promise 来解决什么问题?

  1. 链式调用导致代码 nightmare(困难),通常第一个函数的输出会被第二个函数作为输入使用。
  2. Promise能够有效地处理多个并发请求;获取这些请求中的数据可以通过这个 promise来实现;它能够解决异步的问题;但本身不是异步的。

19. 请简述 async 的用法

异步函数本质上就是生成器和Promise的糖纸。异步函数会将生成器转换为异步执行的方式,并调用 await关键字来实现同步执行。

在函数定义前需添加一个 async关键字,在执行异步操作的方法前应预先添加await关键字。其作用是指示程序先完成当前操作后再继续后续步骤。请注意 await只能在带有async关键字的函数体内使用以避免错误。Promise对象如果返回了一个异常结果,则表示该操作未能成功完成;若未做相应的异常处理机制,则会触发错误。因此可以通过try…catch块来捕获并处理可能发生的异常情况。

20. 一个页面从输入 URL 到页面加载显示完成,这个过程中都 发生了什么?

分为 4 个步骤:

当发送一个URL请求时,无论是否是Web页面上的资源,浏览器都会启动处理该请求的一个线程,与此同时,在远程DNS服务器上发起一次DNS查询,以便获取对应的IP地址。
为了建立TCP/IP连接,浏览器与远端Web服务器之间会协商执行TCP三次握手过程:这一过程包括三个部分:同步报文、同步-应答报文和应答报文;其中,首先由客户端尝试与服务器建立通信;接着是服务器响应并接收客户端的请求;最后是由客户端发出确认该请求已接受。
一旦TCP/IP连接建立完毕,浏览器将向远程服务器发送一次HTTP GET请(命令),而后者则通过HTTP响应返回所需的资源。
远端Web server一旦识别到所需的资源存在后,将通过HTTP响应将其提供给浏览器

21. GET请求传参长度的误区

误区:我们常说GET请求中的参数长度存在一定的限制,在这种情况下相比而言,在POST请求中没有这样的长度限制。实际上,并未有HTTP协议对GET/POST方法下的请求长度设定具体数值。事实上这些服务通常会对URL进行长度控制进而影响到相应的方法应用范围为此我们必须再次强调下面几点:

HTTP 协议 未规定 GET 和 POST 的长度限制

GET请求的最大长度受限于浏览器和Web服务器对URI长度的限制。由于不同浏览器和Web服务器对URI的最大限制不同,在支持IE的情况下,默认最大允许大小为2083字节;若仅支持Chrome,则其最大允许大小为8182字节

22. 补充 GET 和 POST 请求在缓存方面的区别

GET/POST 的请求区别,具体不再赘述。

补充一个关于GET操作与POST操作在缓存机制方面差异的说明:GET请求类似于一种数据检索的过程,在不影响系统性能的前提下允许用户获取所需数据,并且无需频繁地与数据库进行交互;因此能够有效利用缓存机制。相反地, POST操作通常用于执行更新或删除等修改性事务,这些事务往往需要直接访问数据库资源,因此不适合采用缓存策略

23. 说一下闭包

其核心机制是获取其他函数内部的局部变量,并且当子函数被外调用时,其所在的父函数的作用域不会丢失或消失。

24. 说说前端中的事件流

在HTML与JavaScript的交互中是以一种基于事件驱动的方式实现的,在网页开发中常见实例包括鼠标点击事件(onclick)以及页面滚动(onscroll)等动作。为了能够向文档或者文档中的元素注册以响应特定事件的发生,“预订事件”的操作通常会使用相应的API函数进行配置。了解特定事件触发的时间点这需要我们了解“事件流”这一核心概念。

什么是"事件流":它涵盖了从网页接收事务顺序的过程,DOM2级别事务流程包含以下几个关键环节。 事务捕获环节属于目标流程事务冒泡环节

addEventListener:addEventListener 是 DOM2 级别新增操作中指定事件处理程序的作用方式... 该方法接受三个参数:需要执行的事件名称... 以及一个布尔值用于指示是在触发还是传播阶段调用事件处理函数...

25. 说一下事件委托

事件委托即指:避免在事件发生位置(DOM地址)处安装监听函数,在父容器中安装。通过冒泡机制使得子容器的DOM地址被记录下来。系统会根据触发的DOM地址类型进行判断,并以实现精准的响应处理。

举例:毫无疑问就是ul标签和li标签的事件监听行为。当我们处理事件时,在li标签上直接绑定会带来诸多不便。通常不直接绑定到li标签而是将它们绑定到其父元素ul标签上。

优点在于能够较为适合地处理动态元素之间的绑定关系,并且新添加的子元素同样具备相应的监听功能;同时还可以通过事件触发机制实现复杂的响应逻辑。

26. JS 的 new 操作符做了哪些事情

new操作符创建新实例并生成一个空对象。该空对象继承自其原型属性所指明的构造函数。在构造函数被调用时返回该实例。

27. 改变函数内部 this 指针的指向函数(bind,apply,call 的区 别)

通过 apply 和 call 设置函数的 this 指向,在这两种方法中第一个参数都表示要指定 this 指向的目标对象。第二个参数中,apply 接受的是一个数组形式的数据结构;而 call 则是采用 arg1, arg2,…这种可变参数的形式。使用 bind 方法后会生成一个新的函数,在这个新生成的功能块中不会立即执行该操作。

JavaScript中涉及的不同位置包括clientHeight、scrollHeight、offsetHeight等。具体区别是什么?

  • clientHeight:表示可视区域的高度(不包括 border 和滚动条)
  • offsetHeight:表示包含 border 和滚动条在内的可视区域高度
  • scrollHeight:代表所有区域的总高度
  • clientTop:表示边框(通常是)border 的厚度,在未指定的情况下通常为
  • scrollTop:代表滚动被隐藏的部分高度。通过 offsetParent 属性指定的父坐标(CSS 定位元素或 body 元素),获取对象距离顶端的高度。

29. JS 拖拽功能的实现

首先涉及三个事件:mousedown、mousemove以及mouseup。
每当鼠标按下发生的时候,
我们使用一个 tag 标识符来标记此动作已触发。
随后会触发mousemove 事件,
并根据此事件的具体方法执行相应的操作。
其中,
clientX 和 clientY 分别表示鼠标的横向和纵向位置。
这些值分别由 offset 值来进行计算,
其中 offsetX 和 offsetY 表示元素在初始状态下的横向和纵向偏移量。
具体来说,
计算当前鼠标的纵向偏移量(即当前位置减去初始位置)。
此外,
拖拽操作基于绝对定位机制,
主要通过调整 left 属性值来进行水平方向上的位移,
而 top 属性则用于垂直方向上的调整。
值得注意的是,
除了上述方法外,
还可以通过 HTML5 的 drag and drop 接口实现相似效果

30. JS 中的垃圾回收机制

必要性

复制代码
    var a="hello world"; var b="world"; 
    var a=b;

此时会调用该字符串对象的销毁方法hello world进行处理,并为后续的垃圾回收腾出内存空间。具体的垃圾回收操作包括清除对象标记和管理引用计数器

标记清除

主要采用引用计数法来进行垃圾回收操作。每当一个变量被压入栈的时候,在程序执行过程中会被标记为"已占用"状态。从逻辑上讲,在这种情况下系统无法释放这些"已占用"的状态所对应的内存空间资源。“已占用”的内存空间一旦没有得到及时释放,则会继续累积下去,并且由其他函数调用所占据而难以释放出来。只有在退回到堆栈的时候,“已占用”的内存才会被逐一释放并归还给系统使用。

当垃圾回收器运行时,在内存中存储的所有变量子都会被赋予特定标识符。随后程序会依次检查环境中存在的变量子及其引用关系,并根据预设条件性规则对不必要或无用的对象进行去标签处理。随后系统会将所有带有标签标识的对象从内存中移除并进行永久删除操作。最终该程序完成整个循环操作后实现了工作空间资源的有效清理并将其释放出来的资源返还给系统使用

引用计数法

另外一种相对不常见的方法是采用引用计数法。其含义即为每个对象未被引用的数量。具体而言,在定义了一个变量并为其赋以一个引用来表示类型时,默认情况下该对象未被其他地方访问或使用(初始状态),因此其被引用于当前场景的数量为1个;然而,在某些情况下如果某个包含对该对象进行访问操作的地方又获得了另一个新对象(或新实例),则会将当前对象所处的那个场景中的被引数量减去1;当该对象最终被引用于达到零时(即无法再通过任何路径访问到它),系统会将其占用的空间释放出来以便供后续的操作使用(例如垃圾回收机制)。

用引用计数法会存在内存泄露,下面来看原因:

复制代码
    function problem() { 
    var objA = new Object(); 
    var objB = new Object(); 
    objA.someOtherObject = objB; 
    objB.anotherObject = objA; 	
    }

在该示例中, objA和objB通过各自的属性实现了相互引用,从而使得每个对象被引用了两次.在采用引用来计数的方法时,由于函数执行完毕后这两个对象退出了作用域区域,当函数完成运行且计数不为零时,若这种相互引用现象普遍存在将会导致内存泄漏.特别是在DOM对象中,这种情况也会频繁发生:

复制代码
    var element=document.getElementById ( ’‘ ); 
    var myObj=new 
    Object(); 
    myObj.element=element; element.someObject=myObj;

这样就不会有垃圾回收的过程。

31. JS 监听对象属性的改变

参考回答:

我们假设这里有一个 user 对象,

在 ES5 中可以通过 Object.defineProperty 来实现已有属性的监听

复制代码
    Object.defineProperty(user,'name',{ 
    set:function(key,value){ 
    	}
    })

缺陷:当id不在user对象中时,无法监听id的变化(2)。使用Proxy可以在ES6中实现

复制代码
    var user = new Proxy({},{ 	
    set:function(target,key,value,receiver){ 
    }
    })

即使该属性不在 user 对象中定义,同样也可以通过这种方式来监听该属性的变化。

32. 自己实现一个 bind 函数

原理:通过 apply 或者 call 方法来实现。

  1. 初始版本
复制代码
    Function.prototype.bind=function(obj,arg){ 
    var arg=Array.prototype.slice.call(arguments,1); 
    var context=this; 
    return function(newArg){ arg=arg.concat(Arr 	
        ay.prototype.slice.call(newArg)); 
        return context.apply(obj,arg); 
    	}
    }

在处理事件监听中的父本体继承问题时,在新创建一个绑定(bound)过原有父本体生成的新事件监听器时为什么需要考虑?因为当new一个绑定(bound)过原有父本体生成的新事件监听器时(即该新事件监听器被注入prototype chain),它必须满足其继承自原始事件监听器的prototype要求。

复制代码
    Function.prototype.bind=function(obj,arg){ 
    	var arg=Array.prototype.slice.call(argu ments,1); var context=this; 
    	var bound=function(newArg){ 
        arg=arg.concat(Array.prototype.slice.call(newArg) 
                      ); 
        return context.apply(obj,arg); 
    
    	}
    
    	var F=function(){} 
    	//这里需要一个寄生组合继承 
    F.prototype=context. 
    prototype; 
    bound.prototype=new F(); 
    return bound; 
    }

33. JS 怎么控制一次加载一张图片,加载完后再加载下一张

  1. 方法 1
复制代码
    <script type="text/javascript"> 
    var obj=new 
    	Image();
    	obj.src="http://www. 
    	phpernote.com/uplo 
    	adfiles/editor/201107240502201179.jpg"; 
    	obj.onload=function()  {
        alert('图片的宽度为: '+obj.width+';图片的高度为:'+obj.height); 
        document.getElementById("mypic").innnerHTML="<img src='"+this.src+"'/>"; 
    }
    </script> 
    
    <div id="mypic">
    onloading……
    </div>
  1. 方法 2
复制代码
    <script 
    type="text/javascript"> 
    var obj=new Image(); 
    	obj.src="http://www.phpernote.com/uploadfiles/editor/201107240502201179.jpg"; 
    	obj.onreadystatechange=function(){ 
        if(this.readyState=="complete") 
            alert('图片的宽度为:'+obj.width+';图片的高度为:'+obj.height); 
        	document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />"; 
    	}
    	}
    </script> 
    
    <div id="mypic">
    onloading……
    </div>

34. 实现 JS 中所有对象的深度克隆(包装对象,Date 对象,正 则对象)

使用递归来能够较为简便地实现对象的深度克隆;然而,在无论是ES6还是ES5环境下实施这种技术都不可避免地存在相同的问题:即仅能执行特定类型对象(如数组和函数)的深层复制操作,并不具备对Number型、String型、Boolean型以及Date型等包装对象进行复制品的能力;此外还需指出的是该方法同样无法处理RegExp类型的复制品

(1) 前文的方法

复制代码
    function deepClone(obj){ 
    var newObj= obj instanceof Array?[]:{}; 
    for(var i in obj){ 
        newObj[i]=typeof 
        obj[i]=='object'? 
        deepClone(obj[i]):obj[i]; 
    }
    return newObj; 
    }

这种方法可以实现一般对象和数组对象的克隆,比如:

复制代码
    var arr=[1,2,3]; 
    var newArr=deepClone(arr); 
    newArr->[1,2, 
    3] var obj={ 
    x:1, 
    y:2 
    }
    
    var newObj=deepClone(obj); 
    // newObj={x:1,y:2}

但是无法复制如包装对象Number、String和Boolean等类型以及正则对象RegExp和Date类型的实例

复制代码
    //Number 包装对象 
    var num=new Number(1); typeof num // "object" 
    var newNum=deepClone(num); 
    
    //newNum -> {} 空对象 
    //String 包装对象 
    var str=new String("hello"); typeof str //"object" 
    var newStr=deepClone(str); 
    
    //newStr-> {0:'h',1:'e',2:'l',3:'l',4:'o'}; 
    //Boolean 包装对象 
    var bol=new Boolean(true); typeof bol //"object" 
    var newBol=deepClone(bol); 
    
    // newBol ->{} 空对象 
    ....

(2) valueof() 函数
每个对象都具备 valueof() 函数。该函数在某些情况下会尝试将对象转换为其对应的原始值;然而,在许多情况下(如数组、函数以及正则表达式等),由于它们是由多个部分组成的复杂结构或执行特定操作的对象(而非单一数据项),因此默认情况下 valueof() 函数返回的是该对象自身。

对于原始值或者包装类:

复制代码
    function baseClone(base){ 
    return base.valueOf(); 
    }
    
    //Number 
    var num=new Number(1); 
    var newNum=baseClone(num); 
    //newNum->1 
    //String 
    var str=new String('hello'); var 
    newStr=baseClone(str); 
    
    // newStr->"hello" 
    //Boolean 
    var bol=new Boolean(true); 
    var newBol=baseClone(bol); 
    
    //newBol-> true

就对包装类对象而言,在实现其复制功能时,默认情况下完全可以用=号来进行操作。实际上并没有深度克隆的概念,在这里我们采用的是valueOf方法来实现这一功能。从语法结构上来说是标准的。

对于 Date 类型:由于其valueOf()方法的存在,在日期类中定义了返回一个基于内部表示的时间戳值的方法;这个时间戳值代表的是从公元1970年1月1日以来经过了多少毫秒。因此,在Date对象的 prototype上我们可以实现克隆方法。

复制代码
    Date.prototype.clone=function(){ 
    return new Date(this.valueOf()); 
    }
    
    var date=new Date('2010'); 
    var newDate=date.clone(); 
    
    // newDate-> Fri Jan 01 2010 08:00:00 GMT+0800

对于正则对象

复制代码
    RegExp: 
    RegExp.prototype.clone = function() { 
    var pattern = this.valueOf(); 
    var flags = ''; 
    flags += pattern.global ? 'g' : ''; 
    flags += pattern.ignoreCase ? 'i' : ''; 
    flags += pattern.multiline ? 'm' : ''; 
    return new RegExp(pattern.source, flags); 
    };
    
    var reg=new RegExp('/111/'); 
    var newReg=reg.clone();
    
    //newReg-> /\/111\//

35. 来讲讲 JS 的闭包吧

闭包是指有权访问另外一个函数作用域中的变量的函数。

一种称为"局部变量集合"的技术被定义为"闭合块"(Closure),这种技术允许我们在调用完相关操作后仍能维持其有效性。值得注意的是,在传统编程语言中,默认情况下不会立即释放到内存中的数据区域会被保留一段时间以便后续使用;另一种实现方式则是将这些数据直接存放在内存中的数据区域而不依赖于显式的显式存储机制。
通过嵌套定义另一个功能模块(如子函数),我们可以创建一个自洽的功能闭环。

为了实现某种功能:匿名自执行函数:我们知道,在不使用var关键字的情况下,默认情况下所有变量都会被追加到全局对象中。这种做法存在明显的缺陷:一方面可能会导致其他函数误用这些共享的变量;另一方面还可能导致全局对象变得过于庞大(因为取值时需要遍历原型链)。或者每次调用函数都需要显式地声明var关键字。而对于那些仅需执行一次的函数而言,在其内部使用的变量无需进行维护。因此我们可以采用闭包的方式进行处理。

结果缓存:在开发过程中,我们常常会遇到处理过程较为耗时的函数对象,在每次调用该函数时都会耗费大量时间资源。因此,在实际应用中我们会采用缓存机制来优化性能:计算完成后将结果存储至缓存中;下次调用时优先从缓存中查找结果;如果未找到则执行计算并更新缓存;如果找到则直接返回已有的结果值以避免重复计算。这种机制通过闭包特性实现了内部状态的有效保持而不释放外部引用资源

36. 能来讲讲 JS 的语言特性吗

  • 基于客户端浏览器运行;
    • 不需进行预编译处理,在运行时直接解析并执行代码;
    • 是一种弱类型语言,在灵活性上有显著优势;不依赖于特定的操作系统,在多个平台上都能良好运行。
    • 属于脚本式编程语言类别之一

37. JS 的全排列

复制代码
    function permutate(str) { 
    var result = []; 
    if(str.length > 1) { 
    var left = str[0]; 
    var rest = str.slice(1, str.length); 
    var preResult = permutate(rest); 
    for(var i=0; i<preResult.length; i++) { 
        for(var j=0; j<preResult[i].length; j++) { 
            var tmp = preResult[i],slice(0, j) + left + preResult[i].slice(j,preResult[i].length);result.push(tmp); 
        }
    }
    } else if (str.length == 1) { 
    return [str]; 
    }
    return result; 
    }

jQuery 相关的知识

1. CSS预处理sass less是什么?为什么使用他们

作为CSS预处理工具的Sass和less均可被视为CSS上的一个抽象组件,并具有独特的语法结构。它们最终会被编译为标准CSS格式。作为动态样式语言之一,less提供了诸如变量、继承和嵌套等动态特性功能。它可以用于客户端运行(依赖Node),也可以在服务端执行(同样依赖Node)。

2. JS 中.call()与.apply()区别

invoke: 调用一个实例的方法;使用另一个实例替代当前实例。
call: 调用一个实例的方法;使用另一个实例替代当前实例。

根据定义可知, both methods involve calling an object using another object to replace the current one, demonstrating their interchangeable nature in invoking functionality. However, their distinction primarily lies in how they handle parameters: the apply method is limited to two arguments, consisting of a new$this object and an array argArray.特别地,当arg不是时需注意会导致错误

这两个方法的作用效果完全一致。其中call和apply的作用即是借用他人的方法来执行操作,并与自身的操作相似。

不同点: 方法传递的参数不同

3. 为什么会造成跨域/请简述同源策略

出现跨域问题的根本原因: 采用前后端分离模式时, 前后端的域名不符, 从而导致跨域访问问题. 在请求过程中获取数据通常采用post/get方式进行.

跨域问题源于 JavaScript 的一致性策略,在此框架下仅当满足以下条件时才可实现互相通信:具体来说就是协议版本号、主机名称以及端口号(如有配置)完全一致时方能允许互相通信;基于此原则 JavaScript 仅限于处理本机域名范围内的事务而不具备跨域名的操作能力。

NetScape提出的协议同源是一种著名的网络安全策略。即协议相同、域名一致以及端口一致的技术也被广泛应用于互联网服务中。出于提高网络安全性的考量,在浏览器设置中仅支持与同一网络域进行通信的接口请求。同时规定了非同源客户端脚本在未经明确授权的情况下无法访问或操作对方资源以防止潜在的安全威胁。

4. 请输出三种减少页面加载时间的方式

  1. 提高图片质量

  2. 在选择 GIF 格式时需要注意其色彩限制

  3. 合并 CSS 链接以减少资源占用(例如将 margin-top 和 margin-left 等属性合并)

  4. 为避免访问 CDN 服务器时出现路径错误(例如 www.campr.com/目录),建议在 URL 末尾添加斜杠以确保正确路由

  5. 设置图片尺寸参数(如果不提供 height 和 width 参数,则浏览器需动态计算图像大小)。这对于大量图片的情况尤为重要。
    当浏览器知道了 height 和 width 参数后,则无需等待即可开始渲染页面内容,并且即使当前无法显示完整图像,在页面上也会预留相应空间以便后续加载其他资源。(从而显著提升了加载速度)

  6. 减少 http 请求(合并文件,合并图片)

5. this 指向

在 JavaScript 中,在大多数情况下,默认情况下(除非有明确上下文),this 指向的是当前运行时环境中正在被调用的那个函数实例;然而,在某些特定场景下(如类方法中),this 可能会指向与其相关联的对象。

在全局层面上,在指定窗口内进行操作。
在其所管理的对象层面上,在自身内部执行任务。
在事件处理过程中,在当前事件的对象上实施操作。

6. 什么是 jsonp 工作原理是什么?他为什么不 是真正的 ajax

jsonp 其实就是一个跨域解决方案。

将跨域请求的数据以js形式无法实现
然而,在同一页面内进行跨域请求可以通过js脚本实现
因此可以通过编写一段js代码来包装所需的数据
然后将其作为函数调用执行
当执行该脚本时会返回对应的响应内容
获取后立即执行该脚本
将获取到的内容作为参数传递给目标函数使用
这样就能成功获取所需的数据了

JSONP 实现机制主要是通过动态生成 script 标签,并启动与之相关的脚本执行回调函数来完成的。

为什么不是真正的 ajax?

  1. 从调用方式看, AJAX与JSONP看似相似,但实质不同。它们的目标都是通过请求一个URL获取服务器返回的数据进行处理,因此jQuery及ext等框架将JSONP视为AJAX的一种封装形式。
  2. 不过,AJAX与JSONP的本质却大不相同.AJAX的核心在于通过XmlHttpRequest机制获取本页面的内容,而JSONP则依赖于动态加载JavaScript脚本的方式获取数据。
  3. 实际上,AJAX与JSONP的区别不仅在于是否跨站请求,AJAX可以通过服务端代理实现跨站请求的能力,而JSONP本身同样支持同源站的数据访问。
  4. 此外(JSONP是一种较为灵活的方式),它并非强制采用JSON格式传输数据,AJAX也是如此;如果你愿意的话,也可以采用字符编码等方式传递数据(不过这种做法不利于提供公开的API服务)。

7. 请掌握 2 种以上数组去重的方式

  1. 调用该函数的方法
  2. 调用lastIndexOf()函数与indexOf()类似,在其中indexOf从头部开始查找结果;而lastIndexOf则从尾部开始查找结果
  3. ES6中的set结构不允许存在重复元素
  4. 先对原始数组进行排序后,在相邻元素间进行比较,并将不相同的结果收集到新数组中
  5. 借助filter和indexOf实现
  6. 通过ES6新增功能结合扩展运算符来实现
  7. 借助set和Array.from()方法实现转换,并利用Array.from生成所需数组
  8. 通过splice配合双重循环的方式来处理
  9. 借助includes来判断元素是否存在

8. 深浅拷贝是什么如何实现?

深拷be: 通过直接复制内存地址进行的操作,并且涉及内容的复制与存储; shallow copye:仅涉及直接复制内存地址。
浅copye: 对于支持 slice 和 concat 方法的对象来说。
使用扩展运算符 spread 实现 deep copye: ... JSON.parse(JSON.stringify()) 不仅适用于 array 还适用 object。
无法复制 function, undefined, symbol.

9. 为什么 JS 是弱类型语言

弱类型的编程语言在功能上与强类型的编程语言不同。在强类型的编程语言中,变量的种类繁多,例如整数型\char\float\Boolean等,在遇到不同类型的变量进行相互转换时通常需要强制转换单位以保证程序正常运行。而 JavaScript 的确只有一种数据类型 var,当为变量赋值时会自动识别数据类型的差异并进行相应的转换单位以确保正确性。

10. 怎么转换 less 为 CSS

  1. 用 node 将 less 文件生成为 CSS 文件
  2. 用 webstorm 自动生成

11. echarts 使用最多的是什么

图表及图表组合

12. for 循环与 map 循环有什么区别

用于遍历对象自身的属性以及继承自枚举属性的情况,在这种情况下会涉及哪些原型链上的属性?map 方法不会被空数组检测到,并且返回一个新数组副本而不影响原始数组。

13. 请写出一个简单的类与继承

创建类有三种:

  1. 主要依赖 function 和 this 关键字
  2. 该方法主要采用 prototype 和 this 关键字
  3. 主要通过 object.create() 方法构造

继承有六种:

  1. 基于原型的继承
  2. 利用构造函数实现构造函数继承
  3. 组合式策略继承
  4. 基于原型的策略实现
  5. Ashby型动态系统实现
  6. 寄生型动态系统采用组合策略实现

14. 同步与异步的区别/阻塞与非阻塞区别

同步(阻塞的)
异步(非阻塞)

比如:同步操作中,双方在一起办公,到了工作时间后,我会叫你在完成当前任务后一同用餐,考虑到您比较忙碌,我会暂时等待您完成工作后再安排一同用餐;而异步操作中,双方依然在一起办公,到了工作时间后,我会叫你在完成当前任务后一同用餐,考虑到您比较忙碌,我会先自行用餐完毕后再等待您完成工作返回用餐

同步(阻塞)异步(非阻塞)这两个关注的是程序在等待调用结果时的状态

15. 重绘和回流是什么

由于部分或全部元素因规模、布局及隐藏等因素的变化而需重新构建的过程称为回流;所有页面均需在首次加载时经历一次回流;这必然是必须发生的。

当发生回流时,在渲染树中受到影响的节点会被标记为失效节点,并被浏览器重构。完成之后,在受影响区域进行绘制即可实现重绘效果。

在渲染树中存在某些元素需要更新其属性,在这些情况下所述的这些属性仅影响元素的外观而不干扰布局,则被称为重绘

16. http 是什么?有什么特点

在互联网应用中具有广泛应用的特性。http被定义为超文本传输协议,在互联网应用中具有广泛应用的特性。其主要采用基于请求-响应的工作模式,并不依赖于会话维持状态,并且无需建立专门的连接机制。

17. HTTP 协议和 HTTPS 区别

互联网层协议用于实现信息的非加密传输特性,在此基础之上https则采用了ssl技术进行数据加密并实现了身份认证功能;两者的通信方式存在显著差异主要体现在通信端口上http采用80号端口而https则使用443号端口;相比而言http连接机制较为简单不依赖会话维持而https协议则是在ssl技术的支持下建立在传统http之上实现了数据加密身份认证以及更高的安全性保障

18. 原型与继承中的prototype复制器与call/apply的区别主要体现在哪些方面?当它们的第一个参数相同时(即原型相同),第二个参数的差异在哪里?

  • apply()接受两个参数:一个是函数运行的作用域(this),另一个是参数数组。
    • 此时该方法(this method)其第一个参数与 apply() 方法相同,然而,在 call() 方法中,则要求传递给函数的这些参数必须明确列出。

19. 箭头函数与普通函数的区别

  • 箭头函数本质上属于匿名函数类别。
  • 它不具备构造功能。
  • 无法绑定 arguments 对象。
  • 缺乏 prototype 属性。
  • 这个值始终与当前上下文中的 this 相关联

20. 什么是 js 内存泄露?

内存泄漏被称为是一块已分配的内存块既无法被程序使用也无法回收直至浏览器进程退出;设为 null 是释放内存的方法。

21. 你如何对网站的文件和资源进行优化?

  1. 文件整合(主要目标是降低 HTTP 请求频率)
  2. 通过文件压缩技术来降低文件传输大小
  3. 利用 CDN 服务托管网络资源
  4. 采用缓存机制提升资源加载速度
  5. 运用 GZIP 压缩算法对 JS 和 CSS 文件进行优化处理
  6. 对元标签、标题元素、关键词和 alt 属性进行优化配置
  7. 优化反向链接结构以增强网站外部链接质量

22. 请简述 ajax 的执行过程 以及常见的 HTTP 状态码

  • 100:这个状态码是告诉客户端应该继续发送请求,这个临时响应是用来通知客户端的,部分的请求服务器已经接受,但是客户端应继续发送求请求的剩余部分,如果请求已经完成,就忽略这个响应,而且服务器会在请求完成后向客户发送一个最终的结果
  • 200:这个是最常见的 http 状态码,表示服务器已经成功接受请求,并将返回客户端所请求的最终结果
  • 202:表示服务器已经接受了请求,但是还没有处理,而且这个请求最终会不会处理还不确定
  • 204:服务器成功处理了请求,但没有返回任何实体内容 ,可能会返回新的头部元信息
  • 301:客户端请求的网页已经永久移动到新的位置,当链接发生变化时,返回 301 代码告诉客户端链接的变化,客户端保存新的链接,并向新的链接发出请求,已返回请求结果
  • 404:请求失败,客户端请求的资源没有找到或者是不存在
  • 500:服务器遇到未知的错误,导致无法完成客户端当前的请求。
  • 503:服务器由于临时的服务器过载或者是维护,无法解决当前的请求

23. 预加载和懒加载的区别,预加载在什么时间加载合适

预设状态:在页面尚未完全载入时,在内存中预先下载所需的资源文件,在实际调用时从缓存中快速调用所需内容;缓存技术中的一种:根据特定的触发条件或用户行为模式,在适当的时候自动执行资源文件的下载与展示过程

24. JQuery 选择器有哪些

基本选择器在使用频率和复杂性上都是最为突出的 jQuery 资料库中最常应用的选择器之一。这种选择器主要根据元素的 ID CSS 类别 以及标签类型等因素来进行定位

ID选择器 #id
描述:根据指定的id对应一个元素 获取单个元素(注意 在网页中 id名称不可重复)
举例:$(‘#test’)选取具有id为 test 的元素

CSS中的类选择器 .class
说明:通过指定的类名筛选出对应的HTML元素并返回一组符合条件的元素
例如,在以下代码中使用 $(‘.test’) 来筛选出所有 class 属性值为 test 的元素。

基于指定的标签名称定位对应的HTML标记语言元素并捕获该集合。例如,在代码中使用$(\texttt{p})时会捕获所有

`标记语言元素。

  1. *
    描述:匹配所有元素,返回元素集合
    示例:$(“”) 选取所有的元素

  2. selector1, selector2,…,selectorN
    描述:将列表中的各个选择器匹配到的一组元素合并后返回一组
    示例:通过$(“p|span|p.myClass”)语法表达式来获取所有

    , 以及class属性值为myClass的所有

    标签的内容

二、层次选择器
层次选择器根据层次关系获取特定元素。

后代选择器 $(\texttt{“p span”) 匹配 <p> 元素中的所有 <span> 元素(注:后裔筛选法会匹配父节点所包含的所有指定筛选结果的子节点,
无论这些子节点处于父子层级关系还是孙孙子层级关系)

  1. 子选择器:"("parent > child")" 使用 (‘#parent > span’) 来实现对 元素的选择(注:子选择器仅用于筛选直接嵌套于父容器的子容器)
  2. 同辈选择器:"("prev + next")" 使用 (‘.one + p’) 来实现对下一个

    同类兄弟的选择(描述)示例

  3. 同辈选择器:"("prev ~ siblings")" 使用 (‘#two ~ p’) 来实现对所有

    同类兄弟的选择(描述)示例

三、过滤选择器
1>基本过滤选择器

  1. :first
    描述:选取第一个元素,返回单个元素
    示例:$(“p:first”) 选取所有

元素中第一个

元素

  1. :last
    描述:选取最后一个元素,返回单个元素
    示例:$(“p:last”) 选取所有

元素中最后一个

元素

  1. :not(selector)
    描述:移除非匹配项的所有元素集合
    此外, 这种选择器用于生成一个包含所有不满足特定条件的元素的新集合
    例如, 表达式 (\text{`input:not(.myClass)`}) 会筛选出 class 属性不为 .myClass 的 <input> 元素

  2. :even
    描述:选取索引是偶数的所有元素,索引从 0 开始,返回元素集合

  3. :odd
    描述:选取索引是奇数的所有元素,索引从 0 开始,返回元素集合

  4. :eq(index)
    描述:选取索引等于 index 的元素,索引从 0 开始,返回单个元素

  5. :gt(index)
    描述:选取索引大于 index 的元素,索引从 0 开始,返回元素集合

  6. :lt(index)
    描述:选取索引小于于 index 的元素,索引从 0 开始,返回元素集合

  7. :focus
    描述:选取当前获取焦点的元素
    2>内容过滤选择器

  8. :contains(text)
    描述:选择包含文本信息为 text 的元素集合
    示例:$(p:contains(‘I’)) 选择包含文本‘I’的元素

描述:获取无内容标记或无直接子节点标记集合。
示例:(\texttt{p:empty}) 获取该标记及其父层中无直接子节点的状态信息。(\texttt{

}标记自成独立状态)

  1. :has(selector)
    描述:具有:has属性的选择器用于选择所有包含由选中器匹配到的对象的所有父级标签
    示例:$(“#section-p:has§”) 返回所有包含至少一个

    子项的对象标签
    注释:例如,在HTML文档中使用此语法时会发现:
    返回所有包含

    子项的对象标签
    例如:

子项1

子项2

  1. :parent
    描述:获取所有带有子元素或直接包含文本内容的父标签。
    示例:$(“p:parent”) 获取所有带有子

    标签或直接包含文字内容的父

    标签(包括嵌套形式如<p><p/></p>或非嵌套形式如<p>仅文字

    )。

  2. 可见性过滤选择器:用于筛选基于可见性的条件。

  3. :hidden
    描述:选取所有不可见的元素,返回元素集合

  4. :visible
    描述:通过:visible伪类选择器获取当前可见的所有元素,并生成目标元素集合
    4> 第4步:使用属性筛选工具根据指定条件生成目标元素集合

  5. [attribute]
    示例:$(“p[id]”) 选取拥有 id 属性的 p 元素

  6. [attribute=value]
    示例:$(“input[name=text]”) 选取拥有 name 属性等于 text 的 input 元素

其中attribute不等于value

该属性引用采用[attribute]^value的方式表示。
此代码块通过...标记显示了如何使用Markdown语法来选择特定的input元素。

该属性引用采用[attribute]^value的方式表示。
此代码块通过...标记显示了如何使用Markdown语法来选择特定的input元素。

  1. 属性值 等于 value;举例说明如下:使用 (("input[name$=text"]) )可以选择具有 name 属性包含 "text" 输入字段。
  2. 属性 等于 value;举例说明如下:使用 $(("input[name=text"]) )可以选择具有 name 属性包含 "text" 输入字段。

[属性~等于 value] 示例:$("input[class~等于 text]")用于选择那些按空格分隔且 class 属性包含 text 的 input 元素。

  1. [attribute1][attribute2][attributeN]
    说明:整合多个字段的过滤选项
    5>表单对象的表单字段过滤选项集(返回符合条件的元素集合)

  2. :enabled
    描述:选取所有可用元素

  3. :disabled
    描述:选取所有不可用元素

注释:获取所有已选择的元素(如单选框),并包括复选框

  1. :selected
    描述:选择所有处于选中状态的选项项(下拉列表)。
    示例:$(“select option:active”) 从提供的选项中获取所有处于选定状态的项目。

25. Jquery 插入节点的方法

append() 会向每个匹配项内部附加所需的内容
appendTo() 是将所有匹配项附加至指定位置,并且此操作与常规操作(A).append(B)相反:即它是先执行a.append(b),然后再反转结果
为了使a中的A项附加至b中的B项,请使用a.prepend(b)
prepend() 会将内容插入到各个匹配项前面

prependTo() 负责处理所有匹配的元素,并将其放置在指定位置之前。实际上,在常规操作中使用的是$(A).prepend(B),而这里是颠倒了这一过程:把 A 放在 B 的前面。

after() 在每个匹配的元素之后插入内容

insertAfter() 执行插入所有匹配元素到指定元素之后。具体而言,在使用该方法时会逆转常规操作$(A).after(B)的行为:也就是不将B插入到A后面而是将A插入到B后面。

before() 在每个匹配的元素之前插入内容

insertBefore() 负责将所有匹配项插入到指定项之前。实际上,该方法导致常规操作被颠倒:即不是插入B在A前,而是插入A在B前.

26. Js 的函数节流和函数防抖的区别

函数节流是指一定时间内 js 方法只执行一次。

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次

函数节流是定义一个变量作为标志位来判断当前代码是否处于运行状态;当确定正在被调用时,则会阻止该函数在此时段的执行并立即退出;若此时函数处于空闲状态,则允许其正常进入该函数进行处理。

实现函数防抖需借助延时器这一工具,在延迟执行过程中涉及的代码当该方法被重复调用时会进行处理。通过清除上次缓存的超时标记 cleartimeout 来重置相关操作后会重新开始处理流程。如果计时已过且无相应事件可被触发则会执行相关的代码段。

27. GET和 POST 不同

  • GET 是通过服务器获取数据的通信方式,在此过程中客户端能够直接访问所获取的数据。
  • 在客户端中使用 GET 方式时会通过 URL 提交数据,并且该数据可以直接从 URL 中查看。而 POST 方式则是在 HTML 头部字段中进行的。
  • 安全性方面存在潜在风险。
  • GET 方法的数据传输容量限定为1024字节以内,在此范围内确保传输效率。而 POST方法则不受此限制。

28. 什么是 csrf 攻击

csrf(跨站点请求伪造)是一种常见的网络安全威胁。攻击者通常会诱导其访问者(通常是已经登录的目标网站的合法用户)访问一个经过精心设计的恶意链接或表单页,在此过程中模拟合法用户的交互行为。随后系统会将此异常行为视为真实的认证请求并予以响应。为了实现这一点系统通常会发送一些伪装成真实用户的指令到远程服务器上从而达到发起跨站脚本(XSS)或其他恶意操作的目的。

Js 中手写一个深拷贝

29. 什么时候用深拷贝 /浅拷贝

无论深浅,都是需要的,当深拷贝发生时通常表明存在着一个聚合关系

当浅复制发生时,意味着系统中存在一定的相似性.例如,在采用复合模式的情况下

当实现一个观察者模式 Observer Pattern,时,就需要实现浅拷贝

Vue 相关

1. Vue 的核心是什么

Vue 是一种用于构建用户界面的分阶段逐步构建的MVVM框架;它主要功能是专注于视图层的设计。

核心思想

  • 数据驱动(视图的内容根据数据的变化而动态地更新)
  • 组件化(有助于代码的复用性和便于重用代码模块...体现为代码之间相互独立且相互之间的作用较小)

2. 请简述你对 vue 的理解

Vue 是一种基于模型-视图-ViewModel(MVVM)模式构建用户界面的渐进式自底向上增量开发框架。其核心理念在于聚焦于视图层,并通过这种设计架构来实现对数据绑定问题的有效解决方案。这一理念旨在支持大型单页面应用以及模块化组件式的开发需求。因此Vue的核心思想是建立在数据驱动的基础上,并采用组件化设计。值得注意的是MVVM的思想基础在于模型(Model)、视图(View)与ViewModel(ViewModel)三者之间的紧密联系。当模型层的数据发生变化时相应的变化会被传递给视图层进行更新。

3. 请简述 vue 的单向数据流

父级prop的更新会被传递至子组件中,并且每当父组件发生更新时其所有的prop都将被更新至最新的值

数据通过父组件单向传递至子组件,并规定仅能进行单向绑定关系建立;同时规定了子组件内部不得直接更改来自父组件的数据内容。(可采用data和computed来解决)

4. Vue 常用的修饰符有哪些

修饰符:
.lazy 当鼠标离开 input 输入框时会触发
.number 将输出字符串转换为数值类型
.trim 会自动去除用户的输入前后的空白字符

事件标志:
.stop 阻止点击事件向上级DOM发送消息并阻止其传递给父容器, 等效于原生JavaScript中的event.stopPropagation()
.prevent 防止执行预先设置的行为, 等效于原生JavaScript中的event.preventDefault()
.capture 用于将事件监听器附加到元素时采用捕获模式, 意味着拥有该事件标志的对象将最先响应
.self 仅作用于本元素及其直接子元素之外的对象
.once 仅执行一次动作

键盘修饰符:

系统修饰符:.ctrl .alt .shift .meta

5. v-text 与{{}}与 v-html 区别

{{}} 将数据解析为纯文本,不能显示输出 html

v-html 可以渲染输出 html

v-text 脚本会将输入数据转换为纯文本信息,并不会生成 HTML 标签。与普通花括号的不同之处在于,在页面加载过程中不会显示为双层的花括号。

v-text 指令:
作用:操作网页元素中的纯文本内容。{{}}是他的另外一种写法

v-text 与{{}}区别:
v-text 与{{}}等价,{{}}叫模板插值,v-text 叫指令。

主要区别在于,在数据量较大时可能会显示大括号字符(即屏幕闪动现象),这种常见现象称为屏幕闪烁:见第 72 页

6. v-on 可以绑定多个方法吗

当需要绑定多个事件时,请采用键值对形式表示为:event\_type: event\_name。若所有绑定的事件均为同一类型,则可通过逗号分隔的方式进行处理。

7. Vue 循环的 key 作用

键值的设置将确保数据的唯一性。在运行过程中会检查相关节点。若无键值,则会遇到dom节点的情况,并清除现有内容并赋予新值;当存在键值时会比较新的与旧的数据,并判断是否需要移动或删除数据项。

8. 什么是计算属性

用于描述一个值如何依赖于其他值(即声明式的描述),当其依赖的值发生变化时(即发生变更),就会触发DOM更新操作(即更新DOM)。
在模板中将数据绑定到计算属性时(即在使用Vue框架的情况下),Vue会根据其所有变化来更新DOM。
每个计算属性包含一个获取器函数(getter)和设置器函数(setter)。调用获取器函数获取当前值(即读取当前数值),调用设置器函数更新当前值(即修改当前数值)。

9. Vue 单页面的优缺点

优点:前端与后端分离设计使得用户体验友好,并且实现单个字符的快速响应。内容变更时无需全局刷新即可完成显示。缺点:此方案导致SEO性能下降,并且初次加载耗时较长(因为初始阶段需同时解析HTML、CSS及JavaScript文件)。此外方案还导致页面结构过于复杂以及完全缺失导航功能。

10. Vuex 是什么?怎么使用?在那种场景下使 用

Vework 是一个专为 Vue.js 应用程序开发的状态管理模式旨在提供一个集中数据存储点以使程序中的所有组件能够方便地进行访问简单来说 Vework 就是 Vue 的状态管理工具

Vuex 有五个属性 state getters mutations actions modules

State 是存储数据的位置,在 typical Vue 对象中通常通过 data字段来实现。其内部存储的数据呈现响应式特性。当 state 数据发生变化时,这将导致相关组件随之更新。可以通过 this.$store.state.xxx 来访问这些状态值。

Getters相当于state中的一种计算属性,在此场景下其主要功能是对state中的数据进行过滤处理,并在调用该属性时会触发特定的行为

将处理数据逻辑的Mutations方法整合到mutations模块中。当触发事件想要更改state数据时,请使用mutations。通过this.$store.commit来执行。为该方法新增一个参数作为mutation的负载(即payload)。

异步操作数据时采用Actions;但通过mutation实现这一功能;借助this.$store.dispatch进行触发;同时Actions还支持负载。

使用场景:组件之间的状态,登录状态,加入购物车,音乐播放

Vuex 使用流程:

下载 vuex

在src下创建store以及 index.js

引入vue和vue,使用 vuex,导出实例对象

在 main.js 中引入,在.vue 文件中使用

11. Vue 中路由跳转方式(声明式/编程式)

Vue 提供了两种路径导航方式

在路由器配置中, name 属性有什么作用?
当配置 router-link 时, 使用 name字段可直接访问对应的路由.
通过name字段不仅可实现导航功能,还可将所需传输参数同步至子路由.

12. Vue 跨域的解决方式

  1. 后端修改 header
  2. 通过 jq 实现jsonp
  3. 采用http-proxy-middleware(配置代理服务器的中间件)

13. Vue 的生命周期请简述

Vue实例的运行流程即为从实例创建到实例销毁的过程,在这一过程中将会有8个钩子函数被调用

createInstance()在创建之前执行
instanceCreated
prepareTemplate()在渲染开始前调用
templateCreated
updateTemplate()在数据更新前调用
templateUpdated
destroyInstance()在对象销毁前调用.
instanceDestroyed

14. Vue 生命周期的作用

给了用户在不同阶段添加自己的代码的机会

15. DOM 渲染在那个生命周期阶段内完成

DOM 渲染在 mounted 周期中就已经完成

16. Vue 路由的实现

前端路由相当于只是更新视图而不发起页面请求。
通过锚点实现切换过程时页面不会刷新。
官方建议采用 vue-router.js 引入 routing 功能。
配置好一个 routing 组件结构。
配置好一个关于 component 的路径映射关系,请问您是否需要进一步的帮助?
将 routes 配置数据注入到 router 对象中。
生成 root 路由实例对象,并将其注册到 router 中.
请确保所有 url 路由都已经正确配置好了。

17. Vue 路由模式 hash 和 history,简单讲一下

Hash模式中地址栏包含#符号, history中没有对应项, history模式下刷新会导致404错误, 必须进行后台配置. 通过JavaScript对location.hash进行操作以更新URL的hash值. 能够通过hashchange事件捕获hash值的变化情况.

HTML5支持了History API这一功能模块来管理浏览器的历史记录。其中最重要的API包括两个:其一用于添加新的历史条目,另一个则直接替代当前的历史条目。这些功能可以在无需刷新操作的情况下完成历史数据的更新与维护。

18. Vue 路由传参的两种方式,params 和 query 方式与区别

动态路由也可称为路由传参,在同一组件中基于不同选项呈现不同内容

在使用方法上:通过 path 引入 query 与通过 name 引入 params 的方式相似。它们接收参数的方式相似,并且具体实现分别为 this.route.query.name 和 this.route.params.name

在 URL 表示中, params 类似于 post 方式,而 query 则类似于 get 方式。这主要涉及安全性问题,通常 params 会比 query 传输更安全。需要注意的是,在刷新页面时, params 的行为与 query 不同

19. Vue 数据绑定的几种方式

  1. 单一的 HTML 字段中使用双大括号 {{}} 进行字符串嵌入式绑定
  2. 通过 v-bind 线程安全机制实现 HTML 属性的动态赋值
  3. 采用双向通信模式连接到 V-Model 模块
  4. 通过一次性同步机制(v-once)实现状态更新,并确保其与 V-Model 的实时同步

20. Vue 注册一个全局组件

Vue.componnet(“组件的名字”{对象 template

组建的内容

})

21. Vue 的路由钩子函数/路由守卫有哪些

全局独享守卫分为两组:
一组为beforeEach事件中的to、from、next操作;
另一组为afterEach事件中的to、from操作。
组件内部的路由状态变化前的守护操作包括:
进入前的beforeRouterEnter、
更新时的update以及
离开前的leave。

22. 在Vue框架中如何实现动态路由设置?有哪些实现方式?如何获取传递过来的数据?此外,在Vue框架中还有一种常见的术语叫‘路由传参’。

动态路由也可称为参数传输方式,
动态路由有两种不同的参数传输方式,
其中一种是通过路径字段引入,
另一种是通过名称字段实现参数传递,
前者使用 this.$route.query.name 获取查询参数,
后者则使用 this.$route.params.name 获取命名参数。

23. Elementui 中常用的组件是什么?请列举你常用的组件及其属性。

Layout 元素布局组件
在Markdown中使用...表示数学公式时,
在HTML中使用标签如 <, >, {, }, ,, . 时,
在CSS中使用变量声明或值如 $, radix, %,:
在JavaScript中使用语句如 =, +=, -= 等赋值运算符

从 Dropdown 菜单中选择

Table 表格
Tabs 标签页
Form 表单
Pagination 分页
Message 消息提示

24. Vue-cli 中如何自定义指令

25. Vue 中指令有哪些

用于循环处理数组、对象、字符串以及数字类型;用于绑定事件监听机制;用于动态地将一个或多个属性与组件关联;用于在表单控件或组件上建立双向数据绑定关系;通过条件判断实现部分元素渲染的开启与关闭;根据布尔表达式的值决定是否显示某个元素;重新设置元素的内HTML内容;更新元素的文本内容字段;跳过当前元素及其子元素的编译步骤;在当前实例上保持编译状态,直到相关实例完成编译过程为止;仅渲染一次该元素

26. Vue 如何定义一个过滤器

过滤器本质就是一个有参数有返回值的方法

复制代码
    new Vue({
    filters:{ 
    myCurrency:function(myInput){ 
    	return 处理后的数据 
    	} 
    } 
    })

使用方法:

复制代码
    <h1>{{表达式 | 过滤器}}</h1>

过滤器高级用法:可以指定参数,告诉过滤器按照参数进行数据的过滤

27. 对 vue 中 keep-alive 的理解

概念 :keep-alive 是 vue 的内置组件,当它动态包裹组件时,会缓存不活动的组件实例,它自身不会渲染成一个 DOM 元素也不会出现在父组件链中
作用 :在组件切换过程中将状态保留在内存中,防止重复渲染 DOM,减少加载时间以及性能消耗,提高用户体验。
生命周期函数 :Activated 在 keep-alive 组件激活时调用,deactivated在 keep-alive 组件停用时调用

28. 如何让组件中的 CSS 在当前组件生效

在 styled 中加上 scoped

29. Vue 生命周期一共几个阶段

创建 加载 更新 销毁

Prior to the creation phase, the system enters a waiting state.]
【After the creation process, it proceeds to handle mount operations.]
【Preceding the mounting process begins with a pre-configuration check.]
【The mounting operation is completed once all necessary modules are integrated.]
【Prior to initiating an update, system logs are cleared to ensure data integrity.]
【Once updated, system parameters are refreshed and validated.]
【Preceding any destruction operations, a final cleanup routine is executed.]
【Following a page reload, the destroy phase initiates, ensuring proper resource release and resetting pending tasks

DOM 渲染在 mounted 周期中就已经完成

30. mvvm 与 mvc 的区别

Model-View-Controller(MVC)体系中可以看到,在这种架构下实现的是一个能够直接访问数据源的逻辑分离层——视图层;由此可见,在这种架构下会包含有与数据源直接关联的内容——即数据信息会被整合到视图中;而从另一个角度来看,则是强调其不变性——即 MVC 体系关注的是数据层与展示层之间的独立性

mvvm 模型 视图 和 vm 形成了模型与视图之间的纽带,在这种架构中 当模型层的数据发生变化时 vm 会检测到这一变化并触发相应的修改

31. Vue 组件中的 data 为什么是函数

当Data被定义为一个函数时,在这种情况下,每个组件实例都拥有独立的作用域,并且彼此之间互不干扰。

如果是在引用类型(对象)中使用的情况下,在编程逻辑中存在多个组件共享同一个存储空间时,则会发现修改任意一个存储位置会导致所有组件的数据受到影响。因此,在编程中可以通过函数返回该对象的副本来进行操作。这使得每个实例具有独立的作用域,并避免互相干扰。从而实现对每个实例的独特处理而不影响其他实例。

32. Vue 双向绑定的原理

Vue 双向绑定就是:数据变化更新视图,视图变化更新数据

Vue 数据双向绑定是通过数据劫持和观察者模式来实现的,

数据窃取行为是技术手段,在对属性进行赋值操作时,程序能够检测到该行为的存在,并且能够通过定义属性来实现对该行为的控制。

观察者模式 当属性发生改变的时候,使用该数据的地方也发生改变

33. Vue 中组件怎么传值

  1. 正向:从父组件到子组件的数据传输机制是将需要传递的信息封装在属性中触发事件。
  2. 逆向:反向传播信息的方式是自定义事件中包含指定名称及相关信息的触发机制。
  3. 兄弟:中央状态管理系统的实现基于EventBus框架,并由Vuum负责实现其功能。

34. Bootstrap 的原理

网格系统的实现原理在于通过设定容器尺寸进行划分。具体来说,在默认情况下将容器划分为12个部分;若需扩展,则可选择设置为24个或32个部分。在此基础上,并根据需求调整内外间距,并配合媒体视图的变化进行优化配置,则能构建出一个功能完善的响应式网格布局方案。

比如 row col-xs-4

36. 如果一个组件在多个项目中使用怎么办

37. 槽口请简述

首先介绍插槽的作用和功能,在设计时需要考虑哪些因素?插槽的位置如何确定?它能实现哪些功能?这些设置有助于确保子组件模板数据能够正确显示在主组件中。

命名插槽、Unnamed slots以及Scope-based slots属于UIkit中的重要组成部分,在其基本概念下表示的就是组件属性的存储位置

可以在父组件中使用 slot-scope 从子组件获取数据

38. Watch 请简述

Watch的作用是监控一个值的变化,并调用因为变化需要执行的方法

39. Vant Ui 请简述下

轻量、可靠的移动端 Vue 组件库

40. 计算属性与 watch 区别

Compared to a standard watch, Computed watch differs in its caching mechanism. When irrelevant data changes, it directly uses cached values without recomputing. Calculation attributes are used to declaratively describe how a value depends on other values, and they will change when the dependent values or variables change.

watch is designed to monitor the variable defined within the data container. When this variable changes, it will automatically trigger the corresponding methods within watch.

41. mvvm 框架是什么?它和其它框架(jquery)的区别是什么? 哪些场景适合?

Mvvm与传统Vue框架的主要区别在于其以数据为中心的动态组件生成方式,在展示视图时不再依赖传统的DOM节点操作;这种架构特别适合需要处理大量数据处理需求的复杂应用场景

42. 导致首屏加载缓慢的因素有哪些?有哪些解决方案?如何确定白屏发生的时间段?有哪些方法来修复白屏现象?

首屏加载慢的原因:
第一次加载页面有很多组件数据需要渲染

解决方法:

  1. 路由懒加载 component:()=>import(“路由地址”)
  2. ui 框架按需加载
  3. gzip 压缩

白屏时间检测: ????

解决白屏问题:

  1. 使用 v-text 展示数据
  2. 通过{{}}语法呈现数据,并结合 v-cloak 指令(用于保持元素状态直到关联实例结束时进行编译)。需要注意的是:
    • v-cloak 并不需要添加到每个标签
    • 只需在其 el 挂载的标签上添加即可

43. Vue 双数据绑定过程中,这边儿数据改变了怎么通知另一边改变

数据劫持与观察者模式
Vue的数据双向绑定机制主要通过数据劫持与观察者模式实现。data hijacking 的主要目的是确保在设置属性值时能够有效限制其范围,并对其他相关属性产生影响。

观察者模式的主要功能是在属性发生变化时导致这些地方随之更新

44. Vuex 流程

在Vue组件中, 使用dispatch方法发起actions来提交数据修改操作, 随后通过actions的commit事件引发mutations来执行数据修改, 当mutations接收commit事件的请求时, 从而会自动利用mutate方法来更新state, 最终由store触发每一个调用它的组件完成状态更新

45. Vuex 怎么请求异步数据

随后,在 state 中创建变量

在Mutations组件中对state进行状态更新,并通过从action获取的数值来重新赋值该状态

46. Vuex 中 action 如何提交给 mutation 的

该Action函数接受一个与Store实例保持一致接口及属性的Context对象,并可通过调用Context.commit提交一个Mutation请求;此外还可以通过Context.state以及Context.getters获取相关的State信息与Getters功能

47. Route 与 router 区别

  1. router 是 VueRouter 实现的一个核心组件,在使用Vue Router框架注册该组件后,并通过其构造函数生成具体的实例。该实例作为一个全局管理器整合了所有相关的路由信息以及核心属性设置。
  2. route 是用于实现跳转功能的核心组件,在每个路由配置中都会对应生成一个独立的route实例。作为一个局部管理单元能够动态获取请求路径、参数配置以及相关的查询条件设置。

49. vuex 的 State 特性是?

存储位置即为数据源的具体存放地。
该存储区域中的数据具有动态更新特性,在state发生变化时,
会导致相关组件发生相应变化。
利用mapstate机制,
将整体状态及获取器与当前组件的计算属性实现了关联。

50. vuex 的 Getter 特性是?

该组件的 getter 可用于 state 的计算操作;它充当了 store 的计算属性角色。同一个 getter 实例可以在多个组件间共享使用;若某个 state 仅在单一组件内被引用,则无需为该 state 定义 getter。

51. vuex 的 Mutation 特性是?

更改为 vuex store 中更新状态的仅此方式是提交 mutation,在回调函数中即可执行该操作

52. vuex 的 actions 特性是?

Action 类似于 mutation,在不同之处在于它会提交 mutation而非直接更改状态,并且能够包含任意数量的异步操作。

54. vuex 的优势

优点:实现了跨父-child组件的数据互通,并降低了对AJAX请求的依赖程度。其中一些项可以直接从状态存储中读取。缺点:在刷新页面时,在刷新后应用会在网页上重新加载数据。此时vuex的状态会被重置到初始值。解决方案是采用vuex-along组件,并且需要与计算属性以及session storage组件协同工作以实现功能

55. Vue 路由懒加载(按需加载路由)

56. v-for 与 v-if 优先级

建议不要将v-if与v-for同时放置在同一元素中。主要原因在于v-for具有优先级优势,在每次遍历都需要覆盖整个数据集时可能会导致性能下降,并尤其在仅需渲染一小部分数据时更为明显。

v-for 比 v-if 具有更高的优先级

57. 请写出el5 个组件

长提示弹窗

58. vue 在 created 和 mounted 这两个生命周期中请求数据有什么区别呢?

具体情况要看实际需求,在 created(或 beforeRouter) 期间通常是可以配置的。如果是需要等待页面加载完成后再进行操作,则使用 mounted。
当创建视图时,请注意视图中的 HTML 在此阶段尚未渲染完成。因此,在此阶段直接操作 HTML 的 DOM 节点会发现相关元素缺失。
一旦进入 mounted 状态后会先渲染并显示 HTML 内容。因此可以直接对 DOM 元素进行操作。(例如,在这种情况下使用 document.getElementById() 就能正常工作了)

59. 说说你对 proxy 的理解

vue 的数据劫持有两个缺点:

  1. 不具备对数组索引修改后值变化进行监听的能力
  2. Object 的值变化无法被监听到因此在 Vue 2.x 中引入了$set 属性。

Proxy作为ES6推出的一种新API,并且能够解决之前的问题。因此,在Vue 3.x版本中使用Proxy替代了Object.defineProperty。

60. Vue3.0 是如何变得更快的?(底层,源码)

  1. diff 方法优化
    Vue2.x 中的虚拟 dom 是进行全量的对比。

  2. Vue 3.0 中引入了静态标记(PatchFlag),其作用是在与上一个虚拟节点比较时识别带PatchFlag的节点,并利用flag的信息确定当前节点需要对比的具体内容。此外还实现了hoistStatic 功能。
    而Vue 2.x版本则对所有元素均会重新创建,在每次渲染过程中不断重复创建。
    相比而言Vue 3.0版本则优化为仅对不参与更新的元素执行单次创建,并在此后每次渲染时持续复用这些元素。

  3. cacheHandlers 事件监听器在默认情况下会将onClick视为动态绑定行为。每次都会检测该属性的变化情况。由于是同一函数,因此不会检测到属性的变化从而实现属性值的快速复用。

React 相关

1. fetch VS ajax VS axios

传统的Ajax最初被提出作为发送后端请求的技术之一,并源自于原始js领域,在其核心主要基于HttpServletRequest对象的实现方式。当存在前后顺序时就会出现所谓的"callback hell"现象。而jQuery AJAX则是对其进行了封装与优化处理

axios 是一种基于 Promises 的技术;它本质上也是一种对原生 XHR 进行封装的方式;只是它具体化地实现了这一功能,并符合当前的 ES 规范要求。

fetch并非AJAX功能的额外封装形式,并非基于原始JavaScript实现的功能扩展或包装形式;相反地它是独立开发的一个JavaScript实现方案并未采用XML Request对象

2. React 事件处理—修改 this 指向

  1. 该方法通过实现本地化绑定的方式, 进而使 this 指针指向本地资源。
  2. 采用箭头函数的形式。
  3. 在构造函数中, 在初始化阶段就对事件进行了绑定了。
  4. 将事件处理逻辑转换为使用箭头函数的形式。

3. 请简述你对 react 的理解

React 起源于 facebook,react 是一个用于构建用户界面的 js 库

特点:

  • 面向表现的设计:React采用面向语法的声明方式,默认情况下即可实现显性内容展示。
  • 高效率:React通过模拟DOM的行为(即虚拟DOM),最大限度减少与DOM交互。
  • 灵活性:React能够很好地与现有的库和框架协同工作。
  • 组件:将页面的功能拆解为独立的小模块,则每个小模块即为组件。
  • 单向数据流:基于单向数据流模型运行,在这种架构下,默认情况下props从父节点传递到子节点,并且当父级某个props发生变化时,则React会重新渲染所有相关的子节点。

4. react 组件之间的数据传递

  • 正向传输参数可采用 props 方式进行
  • 逆向传输参数可采用函数传递的方式,并通过事件机制实现数据调用
  • 同级之间通信常用pubsub-js协议
  • 通过pubsub.publish方法将指定事件名与数据配对发布
  • 采用pubsub.subscribe方法根据指定的事件名称来捕获接收到的数据内容
  • 跨组件间的数据传输通常会借助context机制实现,在具体应用中需先创建context实例,并定义生产者与消费者角色

5. Vue 与 react 区别

相同点

  • 均支持服务器端渲染
  • 基于组件化的开发模式
  • 配合虚拟Dom技术
  • 通过props参数实现父子组件间的数据交互
  • 严格遵循WebComponent规范
  • 基于数据驱动的视图模式
  • 在状态管理方面具有统一性
  • 在使用React时可选Redux
  • 在Vue中则采用Vux
  • 在原生方案的支持上也实现了兼容性
  • 在React中提供了React Native方案
  • 在Vue中则推出了Vite方案

不同点

  • React 在结构上严格限定其视图层为 MVC 模式的框架
  • 钙ium Dom 的实现不同于 Vue,在 React 中必须通过 shouldComponentUpdate生命周期钩子来触发组件更新
  • 组件编写方式存在显著差异:React 强调将 JSX 和 inline 样式嵌入 JS 中实现功能组合;而 Vue 则将 HTML、CSS 和 JS 放在同一文件中进行整合
  • 数据绑定机制不同:Vue 实现了数据双向动态绑定功能;而 React 则仅提供单向的数据流动机制
  • 在 React 中必须使用 setState 方法来更新状态对象;而 Vue 则无需维护 state 对象,默认由 data 属性管理数据状态

6. 请简述虚拟 dom 与 diff 算法

也可称为虚拟节点。它主要通过JavaScript的对象来模拟DOM中的节点,并借助特定渲染方法将其呈现为真实的DOM节点。该方法会因为频繁操作DOM而导致大量的页面刷新和重绘。

该算法将树状数据结构按层次进行拆分,并仅比较同一层的元素。在列表单元中为每个条目分配唯一的键值以实现差异对比。

7. 你对组件的理解

可组合,可复用,可维护,可测试

8. 调用 setState 之后发生了什么?

当 React 执行 setstate 时(或在触发 setstate 后),其传递给组件的参数对象会被与组件当前状态进行整合(或合并),从而引发相应的协调过程(或触发)

在调和的过程中, React 根据更新后的状态生成 React 元素树, 并对整个用户界面进行重绘. 完成元素树生成后, React 自动识别现有节点与新节点之间的差异, 并基于此实现界面的最小化更新.

9. react 生命周期函数

beforeChildRender 在组件渲染前触发
onChildRenderStart 在组件首次渲染完成后立即执行
onChildPropsChange 当组件接收新的属性值时触发
shouldComponentUpdate 判断当前组件是否需要更新其HTML内容
afterChildUpdate 在完成HTML更新操作后立即触发
onChildUpdateEnd 当所有更新操作完成后才执行
"beforeUnmount" 确保销毁该组件之前有相关操作完成

10. 为什么虚拟 dom 会提高性能?(必考)

虚拟dom类似于在js和真实dom之间建立了一个缓存机制,在实际应用中通过采用dom diff算法来减少不必要的dom操作,并因此提升了系统性能水平

11. (组件的)状态(state)和属性(props)之间有何不同

State 与 props 区别

Props 作为来自外部的一个关键参数,在实现父与子之间数据交互方面发挥着重要作用。然而对于依赖它的模块而言它是不可编辑的核心属性一旦被赋值即无法更改若需更新其状态则需依赖外部主动传递新的 props 给子模块完成重新渲染

Determine the display state of a component by data storage and external parameters, where external parameters are referred to as props, and data storage corresponds to the concept of 'state'. During component initialization, 'this.state' is used to pre-assign an initial storage entity to the component, which is then utilized in the first rendering process. When there is a single-value difference between 'state' and 'props', it indicates that 'state' can be modified through the 'this.setState()' method to achieve dynamic updates based on varying conditions or user inputs.

12. shouldComponentUpdate 是做什么的

该 hook 函数旨在解决在更新数据时整个组件需要重新渲染的问题:通过 setState 更新整个数据,在数据发生变化后会触发组件所有内容的重新渲染操作;当数据量较小时仍能保持较好的性能水平

解决办法:

  1. shouldcomponentupdate在渲染之前判断组件是否已更新,并根据结果决定是否重新渲染。
  2. 纯组件(purecomponent)通过跳过生成虚拟dom和对比过程,在类组件场景中实现高效运行。
  3. React.memo()类似于纯组件,在无状态组件场景中被采用。

13. react diff 原理

它是基于三个策略:

在tree diff web UI中,DOM节点跨层级的操作数量极少,在进行component diff时,同类组件会产生相似的树形结构;而不同类组件则会产生不同的树形结构。

element diff 在同一层级的多个子节点中使用唯一标识符来进行区分

14. 何为受控组件

React 负责处理表单渲染相关的工作, 其中值来源于 state 控制的部分用于获取输入信息, 将表单元素称为受控组件是一种常见的术语表述

15. 调用 super(props) 的目的是什么

通过super()实现对父类构造方法的调用,在实际应用中需要注意以下几点:只有当组件内部定义了this时才会出现;该属性可以在整个组件范围内访问。若仅定义了constructor而不执行super()(如仅在构造函数中声明但未执行),则后续引用会导致错误;同时需要明确的是:通过这种方式能够继承父组件定义的this属性。

16. React 中构建组件的方式

自定义组件:函数组件或者无状态组件 组件首字母大写

class component: 一个 class component 必须实现一个 render method, 该 method 应返回一个 JSX 元素, 并需要用外层元素将所有内容包裹起来.

17.简述 flux 思想

Flux 的最大特点,就是数据的"单向流动"。

  1. 用户被指定为访问该View。
  2. 该View被指示执行用户的Action。
  3. 当Dispatcher接收并接收到来自Action的消息时,在Store中触发相应的更新操作。
  4. 在完成所有必要的Update操作之后, 系统会发送一个标记为"change"的事件通知相关的处理单元。
  5. 当该View接收到"change"事件时, 它会自动重置或重构界面以反映最新的状态信息。

18. React 项目用过什么脚手架?Mern? Yeoman?

Mern:MERN 是一个用于构建应用的框架,在集成 MongoDB、Express、React 和 Node.js 等技术时展现出极高的灵活性与易用性。它显著降低了安装门槛,并帮助开发者快速整合已有的成熟技术以提升开发效率。

19. 应该在 React 组件的何处发起 Ajax 请求?

对于 React 组件来说,在组件初始化阶段(即在 mount 过程中)执行网络请求是一个必要操作。该操作会在组件首次mount到DOM时自动触发,在整个组件生命周期内只会被执行一次。因此,在未完成Ajax请求的情况下尝试调用 setState 在一个尚未mount的组件中将是无效的操作。通过将网络请求提交到 componentDidMount 方法中,则可以在所有组件都已mount后进行状态更新。

20. 何为高阶组件(higher order component)?

高阶组件是一种接收现有组件并生成新组件的功能模块。它通过执行特定操作实现代码复用与逻辑抽象的提升。最典型的是Redux中的connect方法。除了提供简单的工具集与组合功能外,在复用组件行为方面表现尤为突出。当您在多个地方重复编写相同功能的代码时,请考虑将其重构为可复用的高阶组件形式以提高效率与可维护性

小程序相关

1. 小程序的优势

无需进行下载与安装步骤(无需下载安装),操作简便(直接使用),运行效率高且响应迅速(运行速度快),项目搭建过程耗时少且流程清晰(项目搭建迅速),应用规模简短精炼(短小精悍),每个应用的源代码文件大小控制在2MB以内(每个 app 源代码不超过 2mb)

2. 小程序的页面构成(4 个文件)

Index.js index.json index.wxml index.wxss

3. 小程序的生命周期

  1. 在加载时执行
  2. 显示操作发生时
  3. 在隐藏的同时进行卸载操作
  4. 在弹出菜单后自动刷新页面
  5. 达到屏幕底部后触发
  6. 发送共享消息至应用层

4.小程序如何请求数据

用 request

5. 如何提高小程序的首屏加载时间

  • 异步请求无需等到页面渲染完成
  • 在二次启动时先展示预加载的数据以减少渲染时间
  • 即时地为需用户等待的操作提供反馈可让用户误以为小程序未响应
  • 避免不当使用 setdata 和 onpagescroll 以提升性能
  • 提前展示基本布局以防止初始加载出现空白页面

6. 请简述你经常使用的小程序的组件

View icon text image swiper navigator input button map

7. Wxss 与 CSS 的区别请简述

Wxss 增加了新的长度单位 rpx。
Wxss 支持全局样式配置和局部样式应用。
Wxss 仅限于id和class元素等特定CSS选择器。

8. 小程序如何实现响应式

rpx

9. 怎么优化小程序

优化网页加载效率

10. 小程序如何显示用户头像与用户名

目前支持传统的wx.getuserinfo接口,并且在使用过程中会收到官方系统的提示信息。该方法已达到升级版本要求。
最新采用open-data标签的技术方案具有显著优势:通过该标签能够直接获取用户的头像信息及其用户名字段。
在按钮组件中设置opendata属性即可实现功能。

11. 请谈谈小程序的双向绑定和 vue 的异同?

Vue双向绑定采用数据拦截与观察者模式进行机制设计,在组件生命周期中实现前后端的数据交互。借助this.value属性实现前端与后端之间的数据传递,在处理逻辑中调用this.setData函数以传递键值对。对于小程序而言,则采用触发表单元素事件的方式进行表单处理,在处理逻辑中调用this setData函数以传递键值对

12. 小程序中传参是怎么传的

13. 和 vue 类比介绍

14. 说一下微信小程序的适配问题

15. 小程序页面间有哪些传递数据的方法?

16. 你是怎么封装微信小程序的数据请求的

17. 说一下微信小程序的适配问题

18. 小程序跳转页面的方式

19. 微信小程序如何跳转到其他小程序

20. 小程序加载过慢的解决方式

其他

1. Typescript 是什么 请简述?

2. Typescript 与 javascript 的优势?

3. Webpack 与 gulp 区别

Gulp 是一种专为提升前端开发流程效率而设计的工具, webpack 是一种模块化实现(grunt)

4. 请简述 webpack 中的 loaders 与 plugin 的区别

Loader的作用是什么?Loader(即loaders)作为软件系统中的重要组件之一,在其运行过程中主要负责识别并加载各种类型资源文件,并对其进行相应的处理流程。其核心职责是识别并加载各种类型资源文件,并对其进行相应的处理流程包括但不限于编译处理和压缩操作等基础服务工作。在完成所有必要的数据转换与优化后,Loader系统会将所有处理后的结果整合打包至预设的目标文件中。

什么是Plugin?在webpack运行过程中会产生多个事件,在这些关键阶段中插件能够监控并响应相关的变化

区别在于:它是专门用于加载文件的工具;而像 Webpack 这样的工具通常只内置了 Babel 转换器来处理 JS 文件;因此就需要额外安装其他类型的加载器;例如用于处理 CSS 和文件式的负载器如 CSS-Loader 和 File-Loader。

插件旨在增强websitwavelets的功能.借助插件的帮助, wavelets能够实现那些普通的loader无法完成的复杂功能.

5. 怎么提升页面性能?性能优化有哪些?

6. Node 使用来做什么的

能够在服务器端运行 JavaScript

Webpack:入口,出口,加载器,插件

7. 说一下 webpack 的打包原理

Webpack将整个项目视为一个整体,并通过指定一个启动脚本来开始识别和收集项目的依赖项。随后,Webpack会从该启动脚本出发识别并收集项目中所有的依赖项,并通过使用特定的加载器类完成相应的处理工作。最终生成一到多个经过解析的JavaScript文件并进行打包输出。

8. Commonjs ES6 模块区别?

该模块采用复制的方式,并且允许修改值;而 es6 类型采用引用类型,并且只读属性无法被修改。此外,在运行时阶段会加载 commonjs 类别,并且 es6 类别会在编译阶段生成接口定义。

9. Git 如何使用/常用指令有哪些

10. 你们后台用的是什么技术

11. 你的项目比较小为什么还是用 vue 全家桶

12. 请简述你在项目中使用的 ui 框架

13. 什么是 cors

14. 说一下对 websocket 的理解

Websocket 是一种支持双向通信的网络协议,在建立连接后,客户端与服务器均可主动发送或接收数据。为了实现功能的一致性与兼容性,Websocket 需要通过与 TCP 类似的握手机制建立客户端与服务器之间的连接。只有在握手过程建立成功后才能实现有效的通信。

15. 后台传递过来的数据是那些

16. 谈谈 Ajax,fetch,axios 的区别

企业中的项目流程

1. WEB 前端项目开发流程

项目需求分析
这一环节由项目经理负责,在进行项目需求分析之前, 项目经理会先与客户进行沟通, 并详细了解客户需求情况. 接下来, 项目经理会对项目的实施可能性进行评估. 如果项目能够顺利实施, 项目经理将根据实际需求生成一份详细的需求文档, 然后将此文档提交给设计师完成后续开发工作.

在这一环节中,UI 设计师主要参与基于产品需求分析文档的整体美术风格规划以及交互系统的设计工作。他们负责规划产品的整体布局(如页面布局)、交互流程(如操作步骤)及视觉表现(如颜色搭配和排版)。同时承担项目中各类交互界面(如图标)、LOGO标识以及按钮等关键元素的设计与制作工作,并确定采用的技术方案。

这个部分由开发人员负责完成。(这部分包括WEB前端开发人员和后台开发人员。前端开发人员主要负责创建用户可见的界面元素及交互体验;而后端开发人员则专注于构建不可见但至关重要的管理系统和服务功能。)在项目实施过程中,开发团队将根据UI设计团队的需求使用代码语言编写所有功能模块的具体实现内容。

测试
这部分由程序测试人员来完成。程序测试人员的主要职责是检测程序中是否存在bug(Bug)。通常情况下刚完成编码的程序可能会存在一些问题(Bug),因此需要由测试人员反复进行测试,并将发现的问题反馈给编码人员进行修复(Fix)。等到所有已知存在的bug均已修复完毕后,这个项目就可以进入上线准备阶段并基本完成。

项目维护工作作为最后一个阶段进行。 项目维护工作同样是耗时最多的并且成本最高的任务。 项目维护工作不仅包括上线后出现的问题修复与系统版本更新。

替换后端接口为测试后的域名,在开发阶段使用后端接口进行请求路由。

常使用的工具

  • 代码管理平台采用GitHub及码云。
    • 需求发布平台通过钉钉任务和禅道实现需求发布。
    • UI交互平台采用蓝湖。
    • 产品原型工具基于AXURE构建。
    • 企业邮箱支持使用阿里及腾讯的企业邮箱。
    • 后台语言包括Java、PHP、Python(其中西安地区较少)。

2. 大公司和小公司开发的区别

大型外包公司更倾向于遵循严格的流程体系,在组织架构上具有较大的规模优势,并且由于其性质决定了部门间协作效率较低,在项目完成后通常不会承担后续维护责任。主要采用瀑布式开发方法(以文档驱动)。小型企业则相反:员工较少、需求变更频繁但内部信息交流较为顺畅,并主要采用敏捷开发模式(迅速发布第一个版本并进行持续改进)。

3.前后台分离怎么测试?

奇葩问题

1. 你们后端开发用的什么?

2. 移动端如何刷新页面?

3. 项目初始化构建流程

4. 项目中自己觉得骄傲的地方?

5. 说说自己的缺点

6. 热部署是什么?

7. 用户有多少

8. 怎么调用接口(是怎么跟后台沟通的)

9. 单元格测试是怎么做的

10. 开发环境,测试环境,上线环境的环境变量你们在开发中是如何 处理的

全部评论 (0)

还没有任何评论哟~