前端常见面试问题 part 3

下面的大部分问题来自Github的这个仓库,排名不分先后

46. html5中元素的data-*属性

用来存储用户自定义数据,可以通过Element.dataset.foo的形式读取。

47. CSS在前JS在后是一定的么

不。调试js,日志脚本,shim或polyfill以及动态修改整个页面style的JS代码需要放在<head>中。

48. progressive rendering

渐进式渲染技术是一种尽量快地将渲染结果展现给用户的技术。比如懒加载,优先渲染高优先级元素等手段。目标是将用户关心的内容优先展示出来,将页面信息一点点释放给用户。

49. normalize/reset CSS

知乎中一段说明写得太好,这里摘录下来。

CSS Reset 是革命党,CSS Reset 里最激进那一派提倡不管你小子有用没用,通通给我脱了那身衣服,凭什么你 body 出生就穿一圈 margin,凭什么你姓 h 的比别人吃得胖,凭什么你 ul 戴一胳膊珠子。于是 *{margin:0;} 等等运动,把人家全拍扁了。看似是众生平等了,实则是浪费了资源又占不到便宜,有求于人家的时候还得贱贱地给加回去,实在需要人家的默认样式了怎么办?人家锅都扔炉子里烧了,自己看着办吧。

Normalize.css 是改良派。他们提倡,各个元素都有其存在的道理,简单粗暴地一视同仁是不好的。body 那一圈确实挤压了页面的生存空间,那就改掉。士农工商,谁有谁的作用,给他们制定个规范,确保他们在任何浏览器里都干好自己的活儿。

Normalize.css是一种CSS reset的替代方案。Reset清除了所有浏览器默认样式,强调不同浏览器间的一致性。但是在我们需要浏览器默认样式时,就需要自己重头再来。Normalize是两位设计者研究不同浏览器默认样式差异后,设计的弥补浏览器bug保证一致性的CSS。现在大多数的网站已经抛弃了Reset.css而选择Normalize.css。

50. BFC是什么

BFC意为块格式化上下文(block formatting context),BFC表示一个区域,在区域内的所有子元素共同构成一个块级上下文。有4中手段可以触发BFC:

  • position: 不为static和relative
  • display: table-cell,table-caption,inline-block,flex,inline-flex
  • float: 不为none
  • overflow: 不为visible

相对来说通过overflow属性触发BFC对已有内容影响最小。利用BFC可以实现很多特性:

  • 消除box间margin的collapse现象
  • 包裹浮动元素,防止高度collapse
  • BFC不与其他元素相交叉,避免文字围绕图片,实现多栏布局

51. 清除浮动的一些手段

  • 在浮动元素后创建一个空的div标签,为之设置clear: both
  • 触发BFC,一般通过overflow属性触发
  • 使用伪类:after,设置clear: both

52. CSS sprites怎么实现和优缺点

将多张小图拼成大图后,通过background-imagebackground-position更改背景。优点是省流量,更换图标整体风格快;缺点是添加新图片麻烦。

53. 图片替代方案

图片替代指使用图片替代文字,同时保证图片可读,通常用于Logo。有下面几种方案:

  • display: none + background-image
  • text-ident: 9999px + background-image
  • margin-left: -9999px + background-image (盒模型很大,低效)
  • img alt属性
  • font-size或color: #fff

54. 解决browser-specific问题

写patches(独立的CSS文件)处理

55. 如何面对低等级浏览器

polyfill,graceful degration

56. 预处理语言的优缺点

优点:更加友善,更好的特性,语法糖
缺点:需要编译,应用场景局限

57. display有哪些可选值

  • none
  • inherit
  • initial
  • unset
  • block
  • inline
  • inline-block
  • flow
  • table
  • flex
  • grid
  • list-item
  • table-row-group
  • table-row
  • table-header-group
  • table-footer-group
  • table-cell
  • table-column-group
  • table-column
  • table-caption
  • inline-flex
  • inline-grid
  • inline-table
  • inline-list-item

58. translate和absolute的选择

两者并无优劣之分。只有应用场景的不同。translate可以实现复杂的位移和变形,absolute用在固定的定位时更方便

59. 视觉上隐藏一个元素

  1. position: fix + left: -9999px
  2. clip + width/height + overflow
  3. visibility: hidden

60. grid system

除开最新的Grid布局。可以通过inline-block + margin实现。grid布局目前支持还较差。这里是一篇很不错的介绍。

61. 高效的CSS写法

这里有一堆CSS编码风格。总体来说,要注意

  • 避免全局选择
  • 让选择器更加具体化
  • 减少不必要的选择器
  • 减少选择器的过深嵌套
  • 尽可能少使用表达式(即calc, rgba这些)
  • CSS放在头部

62. CSS匹配顺序

先构建DOM树,再从右至左地匹配CSS选择器

63. 盒模型

DOM元素以盒的形式呈现,包裹住真正的内容,有margin/border/padding/content四部分,width在默认情况下仅指content部分的宽度,height同理。若想改变盒模型,可以设置box-sizing属性

64. flex

flex是弹性布局。借助flex布局,可以很轻松地实现居中置右等使用默认方法难以实现的效果。flex布局有两个轴:主轴和交叉轴。元素在主轴方向上排布,在位置不够时,会沿交叉轴推挤到下一行或下一列。flex相关的CSS属性同时针对容器和项目。(下方加粗为默认值)

针对容器的属性有

  • flex-direction 主轴方向。可选row/column/reverse
  • flex-wrap 换行选项。可选nowrap/wrap/wrap-reverse
  • flex-flow 综合上面两个选项,如row wrap
  • justify-content 主轴上对齐方式。可选flex-start/flex-end/center/space-between/space-around
  • align-items交叉轴对齐方式。可选flex-start/flex-end/center/stretch/baseline
  • align-contents主轴间对齐方式。可选flex-start/end/center/space-between/space-around/stretch

针对项目的属性有

  • order 项目顺序,默认按照书写顺序排列
  • flex-grow 当容器主轴上长度足够时,该项目在主轴方向上的长度,默认为1,项目间按照该值比例分配
  • flex-shrink 当容器主轴上长度不够时,类似flex-grow处理
  • flex-basis 容器默认的主轴方向长度,也按比例分配
  • align-self 该项目的对齐方式

65. 适应式/响应式布局

responsive:响应式布局,使用同一种布局响应浏览器窗口的连续变化
adaptive:适应式布局,在视口特定大小时改变外观或样式,是离散的

66. DOM事件代理,冒泡和捕获两阶段

DOM事件代理是指,在DOM2级标准中,事件触发有捕获和冒泡两阶段,所以可以将事件监听器绑定在父节点上,减少EventListener的数目。细节可以参见之前做过的一则笔记

67. null, nudefined, undeclared三者的区别

null: 是Object类型,表示空对象,多用来表示还未赋值的对象
undefined: 是基础类型,表示没有定义的变量或属性
undecided: 只是一种称呼,表示没有用var, constlet声明的变量,默认为全局变量,应该避免出现这种情况

68. 匿名函数的应用场景

主要用作返回值或输入参数。

69. host object和native object的区别

前者是用户定义的对象类型,后者是环境自带的原生对象。尽量避免修改native object(包括增删改)。

70. Function.prototype.bind的使用场景

在setTimeout和listener handler中最常用到

71. feature detection/feature inference/UA

由于浏览器之间有各自的特性差异,这三种手段用于保证代码在浏览器间的兼容性。

  • feature detection 检测特性是否存在再使用,比较保险科学
  • feature inference 通过某特性是否存在推断另一特性是否存在,有风险,避免使用
  • UA 直接通过header中的User Agent来得到浏览器信息,建议迫不得已不使用

72. AJAX技术的优劣

优:用户体验好,局部刷新速度快,可以用于实现界面和数据分离
劣:相对来说较难调试,需要解决跨域问题,搜索引擎支持即SEO弱,会遇到移动端支持问题

73. JS templating

JS中的模板技术,如在backbone中使用的underscore的_.template方法。在xtemplate支持下,也可以在页面中指定<script type="x-template">的形式声明,

74. 如何理解不要改动built-in特性

浏览器和标准都是在不断变化的,此刻对built-in特性做的修改在之后浏览器或标注的呢更新后可能会埋下很深的坑。

75. 如何区分[]和{}

  • Object.Prototype.toString.call()
  • [].concat
  • instanceof
  • ES6中新增的方法Array.isArray

76. tenary operator

JS中唯一的三元操作符

77. DOM中attributes和properties的区别

节点的特性(attributes)用Attr类型表示。直观上讲,特性就是元素attributes属性中的节点,即在tag中声明的各特性名,以下面的标签为例:

1
<input type="text" value="John" />

该DOM节点有两个特性:typevalueAttr也是Node的一种,nodeType为2,Attr对象有三个属性

  • name 特性名称
  • value 特性的值
  • specified 特性是否指定在代码中,抑或是默认的

节点的属性(properties)则指对应的DOM对象的属性,不论是继承自Node或是Element类型的,还是自身类型自带的。比如上面同样的例子,该DOM节点具有children, childNodes, className等。

节点的属性和特性会有重合的部分,如id, type等,因DOM节点而异。上面的例子里,attribute中的value指声明在标签上的value默认值,而properties中的value则指该input标签当前的内容。

78. "use strict";

严格模式在ES5中引入,通过直接定义一个不赋给任何变量的上述字符串进入。可以选择在全局或是函数作用域内开启。

  • 严格模式下对默认模式下会静默出错的代码显式报错
  • 严格模式下禁止不合理的行为,如声明了两个一样的属性名
  • 严格模式还淘汰了一些属性,如arguments.calleearguments.caller; 同时,限制一些不安全的使用,如witheval
  • 严格模式抑制了this的值
  • 严格模式下,对未来版本可能用到的保留字禁止用户访问

不过,由于严格模式下代码的解析规则会不大一样,建议只在需要测试的特定函数内开启严格模式,

79. ready和load event的区别

  • ready在DOM元素加载完成后触发
  • load在页面所有资源请求完成后触发(包括图片、视频、音频等)

80. SPA的SEO优化

采用预渲染技术,或为爬虫专门准备静态页面

81. event loop,call stack和task queue

见这篇笔记

82. JavaScript中的对象和继承

见这篇笔记

不过,在ES6中引入了强类型OOP语言中传统的对象和继承语法。

  • 使用class关键字定义类,类中用constructor定义构造函数,使用publicprivate修饰成员级别
  • 可以在成员前指定getset为成员指定setter和getter函数
  • 通过extends实现继承

83. promise

见之前做过的一篇笔记

84. 提升有滚动条时的动画渲染性能

在CSS中为will-change属性指定动画要改变的CSS属性,参见MDN上的介绍

85. layout, painting, composition

浏览器解析,绘制,组合网页的过程。DOM操作可能会触发回流(reflow)或重绘(repainting),后者代价更小,建议减少频繁的DOM操作

86. 一些HTTP 1.1的header

  • Accept 接受文件的类型
  • Accept-Charset/Accept-Encoding 可以接受的文件字符集和编码
  • Age 从缓存实体产生到现在经历的时间
  • Allow 允许使用的HTTP方法
  • Cache-control 使用的缓存策略
  • Content-Encoding 响应体使用编码
  • Content-Lenght 响应体长度
  • Content-Range 响应体范围,用于部分下载(服务端的返回)
  • Content-Type 响应的媒体类型
  • Date 消息的发送时间
  • Etag html实体的唯一标识,用于缓存对比
  • Expires 缓存实体过期时间
  • Host 服务器的主机名,通常是请求资源的URL
  • Location 重定向的地址
  • Pragma 用于向后兼容还没有Cache-Control的HTTP1.0版本,通常只用作Pragma: no-cache
  • Range 请求资源的部分内容,一般用在多线程下载(客户端发起)
  • Referer 当前请求从哪个地址发起
  • Server 服务器端使用的软件信息
  • Transfer-Encoding 传输内容所用的协议类型
  • Upgrade 切换到额外的通信协议,服务端需要返回101状态码,并指定升级的协议名
  • User-Agent 请求发起自什么终端
  • Vary 列出一个相应字段列表,告知服务器当URL对应不同版本资源时,如何选择合适版本
  • Via 用在proxies中,表示使用的协议,版本以及起始端

更多header参考W3C文档

87. HTTP actions

  • OPTIONS 描述目标资源的通信选项
  • GET 获取数据
  • HEAD 类似GET,但是没有响应体
  • POST 将实体提交给服务器
  • PUT 用请求payload替换目标资源
  • PATCH 对资源部分修改
  • DELETE 删除指定资源
  • TRACE 沿着到目标资源的路径执行一个消息环回测试
  • CONNECT 建立一个到由目标资源标识的服务器的隧道

88. JS内存泄漏

  • 意外的全局变量
  • 被遗忘的setInterval
  • 脱离文档的DOM引用
  • 不合理的闭包

Chrome下可以通过Timeline/Profile选项卡查看内存使用情况,避免上述情况出现。

89. rem,em,px

Question 24

90. JS数据类型

基础类型:

  • Undefined
  • Null
  • Number(包括NaN Infinity)
  • Boolean
  • String

其余都是引用类型。更多参加这里

91. Object.assignObject.create

  • Object.assign 将传入变量的可枚举属性和已有属性合并
  • Object.create 创建一个以传入对象为__proto__的对象

92. 回流和重绘

还是参见how browsers work。为了减少回流,有下面一些推荐实践:

  • 一次性改变样式,如用class
  • requestAnimationFrame推迟回流
  • 虚拟DOM
  • 使用documentFragment

93. 排序算法

稳定:插冒归基;不稳定:快选堆希。实现略。

94. CSS/JS跨浏览器兼容问题

  • 明确产品的兼容版本方案,选择合适的技术栈
  • normalize.css polyfill/shim保证兼容
  • 在符合W3C标准浏览器下表现良好,旧浏览器下保证可用性,提示升级即可
  • CSS hack(特殊的选择器,条件样式表)

95. xss和csrf的防御

XSS(Cross Site Script,跨站脚本攻击),分为反射式,存储式,前者只对特定用户生效,如存储在个人资料中的脚本,后者对访问网站的所有用户生效,如攻击站点本身代码。防御转义时,不仅要监测<script>标签,对可以书写JavaScript的href属性,src属性,甚至imgonerror等事件也要做防御。

CSRF(Cross-site Request Forgery,跨站请求伪造),意为恶意网站通过用户存储的cookie,模拟向其他网站发起“合法”请求。需要注意下面两点

  • 不使用GET方法更新数据
  • 对于POST方法,通过后台生成随机的csrf_token注入到form<input type="hidden">标签中预防

总而言之,不信任用户的所有输入,对输入做处理,避免SQL注入和XSS攻击。


96. CSS属性继承

无继承性:

  • display
  • 文本属性:vertical-align/text-shadow/text-decoration
  • 盒模型属性
  • 背景相关属性
  • 定位属性:float clear top/left/right/bottom z-index
  • 轮廓内容:content outline

有继承性:

  • 字体属性
  • 文本属性:text-align/line-height/word-spacing/letter-spacing/color
  • 可见性:visibility
  • 表格列表:list-style
  • 光标:cursor

行内元素可继承:字体属性,除了text-indent/text-align
块元素可继承:text-align/text-ident

97. 移动端实现0.5px的border

  • 结合:before:after通过transform-originscale实现
  • 利用渐变background-image: linear-gradient
  • 直接使用backgroun-image

98. 随机打乱一个数组

Fisher-Yates shuffle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function shuffle(array) {
let counter = array.length;

// While there are elements in the array
while (counter > 0) {
// Pick a random index
let index = Math.floor(Math.random() * counter);

// Decrease counter by 1
counter--;

// And swap the last element with it
let temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}

return array;
}

99. 移动端fixed定位bug

iOS中,在软键盘唤起后,fixed定位元素会失效,变为absolute定位。解决方案:主体部分设为height: 100%; overflow-y: scroll,通过absolute定位实现。

100. JS如何获知当前页面是否来自缓存

配合后台:后台传递时间戳到当前页面或cookie
无后台:通过xhr放送HEAD请求,得到返回的status code

101. 重复打印字符串

幂次叠加,substr切割字符串。

102. 正则匹配中?:?=的意思

  • ?: 非捕获匹配分组,匹配并出现在匹配结果中,但不作为子匹配返回
  • ?= 前瞻匹配,不出现在匹配结果中

更多参见问题16