前端常见面试问题 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-image
和background-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. 视觉上隐藏一个元素
- position: fix + left: -9999px
- clip + width/height + overflow
- 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/reverseflex-wrap
换行选项。可选nowrap/wrap/wrap-reverseflex-flow
综合上面两个选项,如row wrapjustify-content
主轴上对齐方式。可选flex-start/flex-end/center/space-between/space-aroundalign-items
交叉轴对齐方式。可选flex-start/flex-end/center/stretch/baselinealign-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
, const
或let
声明的变量,默认为全局变量,应该避免出现这种情况
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节点有两个特性:type
和value
。Attr
也是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.callee
和arguments.caller
; 同时,限制一些不安全的使用,如with
和eval
- 严格模式抑制了
this
的值 - 严格模式下,对未来版本可能用到的保留字禁止用户访问
不过,由于严格模式下代码的解析规则会不大一样,建议只在需要测试的特定函数内开启严格模式,
79. ready和load event的区别
- ready在DOM元素加载完成后触发
- load在页面所有资源请求完成后触发(包括图片、视频、音频等)
80. SPA的SEO优化
采用预渲染技术,或为爬虫专门准备静态页面
81. event loop,call stack和task queue
见这篇笔记。
82. JavaScript中的对象和继承
见这篇笔记。
不过,在ES6中引入了强类型OOP语言中传统的对象和继承语法。
- 使用
class
关键字定义类,类中用constructor
定义构造函数,使用public
和private
修饰成员级别 - 可以在成员前指定
get
和set
为成员指定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
服务器的主机名,通常是请求资源的URLLocation
重定向的地址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
90. JS数据类型
基础类型:
- Undefined
- Null
- Number(包括NaN Infinity)
- Boolean
- String
其余都是引用类型。更多参加这里。
91. Object.assign
和Object.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
属性,甚至img
的onerror
等事件也要做防御。
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-origin
和scale
实现 - 利用渐变
background-image: linear-gradient
- 直接使用backgroun-image
98. 随机打乱一个数组
1 | function shuffle(array) { |
99. 移动端fixed定位bug
iOS中,在软键盘唤起后,fixed定位元素会失效,变为absolute定位。解决方案:主体部分设为height: 100%; overflow-y: scroll
,通过absolute定位实现。
100. JS如何获知当前页面是否来自缓存
配合后台:后台传递时间戳到当前页面或cookie
无后台:通过xhr放送HEAD
请求,得到返回的status code
101. 重复打印字符串
幂次叠加,substr
切割字符串。
102. 正则匹配中?:
和?=
的意思
?:
非捕获匹配分组,匹配并出现在匹配结果中,但不作为子匹配返回?=
前瞻匹配,不出现在匹配结果中
更多参见问题16。