1. 浏览器的DOM和BOM
BOM
BOM,Browser Object Model,即浏览器对象模型。
BOM描述了与浏览器进行交互的方法和接口,可以访问和操作浏览器窗口。BOM最根本的对象是window,具有很多浏览器窗口的属性和方法。BOM直接与浏览器相关,与文档无关。
window既是通过js对象访问浏览器窗口的一个接口,又是一个全局对象。意味着在网页中定义的任何对象,变量和函数,都是以window作为global对象。
DOM
DOM,Document Object Model,即文档对象模型。
DOM描述了处理网页内容(文档) 的方法和接口,DOM相当于一棵节点分层分布的树。网页是由服务器发给客户端的,所以DOM与浏览器的关系并不大。DOM最根本的对象是document(window.document),DOM规范解释了文档的结构并提供对象来操作它。
DOM的API可以对DOM树上的节点进行增删改查。document是window 对象的子对象。
2. 描述HTML标签的块级元素、行内元素、行内块元素
HTML的块内元素和行内元素等,可以通过display进行区别。
块级元素block:独占一行,具有宽高行内外距属性
行内元素inline:不独占一行,宽高属性无效,只有水平方向的行内外距属性有效(canvas是行内元素)
行内块元素inline-block:即具有行内属性不独占一行的属性,又能设置宽高内外边距属性
3. 元素垂直居中的方法
- flex布局
- transfrom变形偏移
- position定位
- tansfrom + position
4. 相对定位与绝对定位的区别
相对定位:相对于元素自身原来的位置移动。该属性仍然处于文档流中,不会影响其他元素的布局
绝对定位:在父元素没有设置定位时,会相对于根元素(HTML元素)定位;如果父元素设置了定位,则会相对于离自己最近的父元素(非static)进行定位。会脱离文档流,会影响其他元素的位置
5. 媒体查询
媒体查询@media可以根据不同的屏幕尺寸设置出不同的样式,调整浏览器的大小。
媒体查询可以得到:视窗的宽高、设备的宽高、旋转方向、分辨率大小。
6. rem、em、px的区别
px:相对长度单位,相对于显示屏屏幕分辨率
em:相对长度单位,em相对于当前元素的父元素的font-size计算,若未设置则相对于浏览器的默认字体大小
rem:相对长度单位,相对于根元素(HTML元素)的font-size计算,不仅可以设置字体的大小,还可以设置元素的宽高属性
7. flex布局
参考阮一峰老师的个人博客:www.ruanyifeng.com/blog/2015/0…
8. transition、transform、animation
transition:更适用于简单的过渡效果
transform:只是对于元素的一些属性的转换,transform不会引起页面的重排,可以提高性能
animation:可以实现一些复杂的过渡,具有一些动画属性
9. js的数据类型
js的数据类型分为基本数据类型和引用数据类型。
基本数据类型(栈)
String、Number、Boolean、Null、Undefined(前几个为原始数据类型)、Symbol(Symbol函数的参数只是表示对当前 Symbol 值的描述)、BigInt
引用数据类型(堆)
Object、Function、Array
区别:存储位置不同
原始数据类型存储在栈中,占据空间小,大小固定,属于被频繁使用的数据,所以存放在栈中。
引用数据类型存储在堆中,占据空间大,大小不固定,如果存储在栈中,会影响到程序的性能问题,所以引用类型在栈中设置了指针,该指针指向引用类型的起始地址,检索栈中的指针,通过指针查找到地址中的实体。
判断类型的方法
- typeof
- Object.prototype.toString.call(data)
10. 事件委托
事件委托也就是,将一个(一组)元素的事件委托到父元素(或者更外层的元素)上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件的冒泡机制触发外层的事件绑定。
也就是说,将一个(一组)元素委托给某个元素,当这个元素触发之后,响应的结果会分配到对应的元素上。
事件冒泡模型
冒泡事件模型被分为三个阶段:
- 捕获阶段:捕获阶段不会响应任何事件
- 目标阶段:事件响应到触发事件的最底层元素上
- 冒泡阶段:事件触发响应过程中会从最底层的元素向上延伸,事件代理就是利用冒泡机制将内部元素需要相应的事件绑定在外层上
事件委托的优点
- 减少内存损耗
- 动态的绑定事件
11. const与let
const和let变量声明的作用域是块级作用域
let声明的变量可以重新赋值,但是不能在同一个作用域内重新声明
const变量赋值时必须进行初始化,在同一个作用域内不能重新声明也不能重新赋值
12. 数据的for...of...循环
该循环可以访问任何可迭代(就是除Object)的数据类型。
可以随时停止或者退出循环,不用担心对象中添加新的属性。
for...of只循环访问对象中的值。
13. 箭头函数
- 箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。由于箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数,他们的第一个参数会被忽略。
- 箭头函数不绑定arguments 对象。
- 箭头函数不能用作构造器,和new一起使用会抛出错误。
- 箭头函数没有prototype属性。
- yield关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作函数生成器。
14. ES6新增的map和set
map和set是ES6新增的数据类型。
set
set必须接受数组作为参数。如果要获取数组中的某个数据,必须要先解析数组且需要借助展开运算符。
Set中不允许存储相同的数据,可以用来解决数组去重。
map
map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键,是一种更完善的 Hash 结构实现。
map也必须接受数组作为参数。,且数组为二维数组,二维数组中有两个数据,第三个数据不显示。
15. Vue中的data为什么是一个函数
- Vue的组件是用来复用的,防止data复用,所以data定义为函数
- 防止其中一个组件中的data改变而影响到其他组件中的data,所以需要通过data函数返回一个对象作为组件的状态
- data函数拥有自己的作用域,相当于一个私有的数据库,各个组件只对自己的数据进行维护
- Vue实例都是用的同一个构造函数,防止所有的组件实例共用一个对象data,单个组件中的数据改变也会改变其他组件中的值
16. 深拷贝和浅拷贝
深拷贝和浅拷贝只针对引用数据类型。
浅拷贝只复制某个对象的指针,而不是复制对象本身,新旧对象还是共享同一块内存。深拷贝是完全复制对象本身形成一个新的对象,新的对象与旧对象不共享内存,对新对象进行修改也不会影响到旧对象。
浅拷贝
- Object.assign()(当object只有一层时,是深拷贝)
- Array.prototype.concat()
- Array.prototype.slice() Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。如果该元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里,两个对象引用都引用了同一个对象,如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。
深拷贝
- JSON.parse(JSON.stringify()):使用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,这样就会生成一个新的对象,并且新对象会开辟新的栈,实现深拷贝。
- 递归:遍历对象、数组中的数据知道遇到基本数据类型再复制,则为深拷贝
- 函数库lodash:_.cloneDeep用来深拷贝
17. vue-router底层实现原理
众所周知,vue-router存在两种模式:hash和history模式。
在vue-router模块中,仍然是利用Object.defineProperty()API,将路由做响应式处理; 当路由跳转的时候,执行updateRoute()函数;在Vue.util.defineReactive_route()中将路由响应式处理;在router-view 中判断当前路由,并向显示对应组件;(转载)
Hash模式
hash模式使用的原理是onhashchange事件。
hash模式下,前端路由使用的是#中的信息,可以进行前进和后退。#会触发hashchange事件,即会再次走一次生命周期钩子,也就是会再次调用beforeEnter钩子函数(即触发了两次)。
history模式
history模式是根据history.pushState(),基于h5中的history API。当调用history.pushState时,不会向服务器发送请求,只会改变浏览器路径栏中的地址,并且将地址记录到历史记录中,根据当前路由地址找到对应组件重新渲染。
history模式下,如果服务器没有相应时,会返回一个404(刷新的时候会请求服务器)。