2022前端面试题整理
1. Doctype
声明位于文档中的最前面,处于html标签之前,告知浏览器以何种模式来渲染文档。
严格模式的排版和 JS 运作模式是以该浏览器支持的最高标准运行。
混杂模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。
2. BFC
直译为块级格式化上下文,它是指页面中一块独立的渲染区域,这块区域有自己独立的渲染规则,简单来说,BFC就是一个独立不干扰外界也不受外界干扰的盒子。
布局规则:
- 内部的Box会在垂直方向,按顺序排列。
- Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的Margin会发生重叠,也就是外边距塌陷。
- BFC的区域不会与float盒子叠加。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
- 计算BFC的高度时,浮动元素也参与计算。
触发条件:
- 根元素。
- float的值不为none。
- overflow的值不为visible。
- display的值为inline-block、table-cell、table-caption。
- position的值为absolute或fixed。
3. 行内元素、块级元素、行内块元素
行内元素(span、a、img、input、select、textarea...)
- 行内元素可以并排一行。
- 行内元素设置 width,height 属性无效。
- 行内元素的 margin 和 padding 只在水平方向有效果。
块级元素(div、p、form、h1-h6...)
- 块级元素独占一行,其宽度自动填满其父元素宽度。
- 块级元素可以设置 width,height 属性,但即使设置了宽度,仍然是独占一行。
- 块级元素可以设置 margin 和 padding 属性。
行内块元素
- 结合的行内和块级的优点,既可以设置长宽,可以让padding和margin生效,又可以和其他行内元素并排。
4. 语义化
语义化的主要目的就是发挥标签和属性的作用,通过标签本身的意义合作来优化HTML文档结构。
- 语义化标签会标记出每个区域的作用并且更好是实现页面布局。
- 语义化标签的实现有利于一些特殊设备的解析,比如盲人阅读器。
- 语义化标签能和搜索引擎建立良好沟通,通过标签本身的含义来理解页面内容是搜索引擎分析和理解页面的重要方式之一,使用语义化标签有助于提高页面关键词排名,减少SEO优化难度。
- 语义化更具可读性,是下一步网页开发的重要动向,如果遵循W3C标准的团队都遵循这个标准,可以减少差异化。
5. link 和 @import 比较
- link是 HTML 方式, @import是 CSS 方式。
- link最大限度支持并行下载,@import过多嵌套导致串行下载,出现浏览器样式闪烁。
- link可以通过rel="alternate stylesheet"指定候选样式。
- 浏览器对link支持早于@import,可以使用@import对老浏览器隐藏样式。
- @import必须在样式规则之前,可以在 css 文件中引用其他文件。
6. position 的值
- static: 默认定位。
- relative: 相对定位,相对其在普通文档流中的位置。
- absoulte: 绝对定位,相对于最近一级不是static的父元素定位,默认body,值得注意的是不设置top/bottom/left/right,表现出无依赖定位性质,结合margin布局有奇效。
- fix: 绝对定位,相对浏览器窗口或者frame;
- sticky: 生成粘性定位的元素,容器的位置根据正常文档流计算得出。
7. vertical-align 作用
一种简单的 CSS 属性,用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。
起作用的前提:元素为 inline 水平元素或 table-cell 元素,包括 span , img , input , button , td 以及通过 display 改变了显示水平为 inline 水平或者 table-cell 的元素。这也意味着,默认情况下, div , p 等元素设置 vertical-align 无效。
值得注意的是:例如 float 和 position: absolute ,一旦设置了这两个属性之一,元素的 display 值被忽略,强制当成 block 方式处理,因此,vertical-align 也就失去了作用。
8. 清除浮动
https://www.cnblogs.com/yuwenxiang/p/16579367.html
9. 文本超出部分显示省略号
https://www.cnblogs.com/yuwenxiang/p/16579377.html
10. 水平垂直居中的实现
https://www.cnblogs.com/yuwenxiang/p/16579348.html
11. js 事件代理
事件代理(Event Delegation),又称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。
12. js 数据类型
- 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
- 引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
typeof 返回类型(7种):
typeof 123 => number
typeof 'abc' => string
typeof true => boolean
typeof function fn() {} => function
typeof null => object
typeof undefined => undefined
typeof Symbol() => symbol
13. ES5的继承和ES6的继承区别
ES5的继承是通过prototype或构造函数机制来实现。实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this))。
ES6的继承机制完全不同,实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this。
14. js 的垃圾回收机制
标记清除(mark and sweep)
这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
引用计数(reference counting)
在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的,也就是说只要涉及BOM及DOM就会出现循环引用问题。
15. new 操作符做了什么
- 先创建了一个新的对象。
- 将新对象与构造函数通过原型链进行连接。
- 将构造函数的this绑定到新对象。
- 根据构建函数返回类型作判断,如果是值类型,返回新对象。如果是引用类型,就返回这个引用类型的对象。
16. null 和 undefined 的区别
- null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN。
- 当声明的变量还未被初始化时,变量的默认值为undefined。
- null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
- undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。
17. js 闭包
https://www.cnblogs.com/yuwenxiang/p/16579900.html
18. js 防抖和节流
https://www.cnblogs.com/yuwenxiang/p/16579260.html
19. websocket
https://www.cnblogs.com/yuwenxiang/p/16579949.html
20. js 运算
undefined == 0 // false undefined == false // false undefined == null // true null == 0 // false null == false // false null == null // true typeof null // 'object' NaN == true // false NaN == false // false NaN == NaN // false typeof NaN // 'number' 0 == "0" // true 0 == [] // true "0" == [] // false ['1','2','3'].map(parseInt) // [1, NaN, NaN]