1.react虚拟dom是怎么回事
- 虚拟DOM本质上就是一个对象,和真实DOM相比,它少了默认挂载的很多属性和方法,在开发过程我们并不需要去关心这些属性和方法,所以从结构上来看,虚拟DOM比真实DOM轻很多。
- 从操作角度看,原生DOM要想性能高会带来复杂度,不利于项目开发
- 而虚拟DOM将所有的操作聚集到一块,计算出所有的变化后,统一更新一次虚拟DOM
优势:
- 提高效率: 使用原生js的时候,我们需要的关注点在操作DOM上,而React会通过虚拟DOM来确保DOM的匹配,我们不需要关注如何操作、怎样更新DOM, 我们更关注业务逻辑,从而提高开发效率
- 性能提升:
-
React会将整个DOM保存为虚拟DOM,如果有更新,都会维护两个虚拟DOM,以此来比较之前的状态和当前的状态,并会确定哪些状态被修改,然后将这些变化更新到实际DOM上,一旦真正的DOM发生改变,也会更新UI
-
浏览器在处理DOM的时候会很慢,处理Javascript会很快
-
所以在虚拟DOM感受到变化的时候只会更新局部,而非整体。同时,虚拟DOM会减少了非常多的DOM操作,所以性能会提升很多
-
它的优势在于diff算法和批量处理策略,将所有的DOM操作搜集起来,一次性去改变真实的DOM,但在首次渲染上,虚拟DOM会多了一层计算,消耗一些性能,所以有可能会比html渲染要慢。
-
虚拟DOM实际上是给我们找了一条最短最近的路径,并不是说比DOM操作的更快,而是路径最简单
-
- 超强的兼容性:
- 浏览器的兼容和跨平台兼容
- react基于虚拟DOM实现了一套自己的事件机制,并且模拟了事件冒泡和捕获过程,采取事件代理、批量更新等方法,从而磨平了各个浏览器的事件兼容问题
- 对于跨平台,react和react native都是根据虚拟DOM画出相应平台的UI层,只不过不同的平台画法不同而已
2.js如何创建一个对象
- 字面量
- Object.create()
3.如何清除浮动
- 利用clear样式
- 父元素结束标签之前插入清除浮动的块级元素
- 利用伪元素(clearfix) :after{ content: ''; display: block; clear: both; }
- 利用overflow清除浮动
BFC(块级格式化上下文):
- overflow: hidden,auto,scroll
- display: inline-block, inline-table, inline-flex, inline-grid, flex, table-caption, inltable-cell, table, grid
- position: fixed, absolute
两栏布局:
往往是一个定宽栏和一个自适应栏并排展示
- flex. 父组件display: flex. 左侧子元素固定宽度200px, 右侧子元素flex:1
- 父元素添加BFC(防止下方元素飞到上方展示), 左边栏float左浮, 右侧marginLeft左侧宽度(撑出内容块做内容展示)
三栏布局:
- 浮动。左右float, 中间mārgin:0.
- 绝对定位,左右position: absolute
- display: table \ display:table-cell
- display: flex
- display: grid \ grid-template-columns: 300px auto 300px
flex有三个属性,分别是?
- grow:父容器宽度大于子元素宽度时对元素做出调整
- shrink:压缩
- basis:width
4.如何想让一个元素在页面看不见
- display: none 元素在页面上彻底消失,元素本身占有的空间会被其他元素占有,会导致浏览器的重排和重绘,无法响应点击事件
- visibility: hidden 仅仅是隐藏元素,DOM节点会存在,只是在不可见状态,不会触发重排,但会重绘,无法响应点击事件
- opacity: 0 改变元素透明度,元素不可见,占据页面空间,可以响应事件
- 设置height、width模型属性为0 元素不可见,不占据页面空间,无法响应点击事件,如果有子元素,应该设置其overflow: hidden来隐藏
- position: absolute 将元素移出可视区域,元素不可见,不影响页面布局
- clip-path 裁剪,元素不可见,不占据页面空间,无法响应点击事件
5.react-router的原理
路由的本质就是页面的url发生改变时,页面的显示结果可以根据url的变化而变化,但是页面不会刷新。 因此,可以通过前端路由实现单页(SPA)应用,react-router主要分成了几个不同的包:
- react-router: 实现了路由的核心功能
- react-router-dom: 基于react-router, 加入了在浏览器运行环境下的一些功能
- react-router-native: 基于react-router, 加入了react-native运行环境下的一些功能
- react-router-config: 用于配置静态路由的工具库
6.盒模型
对文档进行布局的时候,浏览器的渲染引擎会根据标准之一的css寄出框盒模型,将所有元素表示为一个个矩形的盒子。
在css中,盒子模型可以分成:
- W3C标准盒模型 : 总宽度 = width + padding + border + margin;
- IE怪异盒模型 : 总宽度 = width + margin (width包含了padding和border的值)
7.页面中的性能优化
- 图片: 压缩,格式webp,懒加载,小图转为base64减少请求次数
- css: 减少重排和重绘, 样式选择器的层级不要太深
- js: 文件压缩,文件分片,对资源进行缓存
- react: memo高阶组件减少不必要的渲染,不需要渲染的数据不要放到state里
8.什么是跨域?如何解决跨域的,jsonp有什么缺点
- 浏览器同源策略限制:协议、域名、端口号中任意一个不同
- 解决方法:
- jsonp
- 原理: script标签的src不受同源策略的限制
- 后端返回一段js代码,代码的内容是一个前端定义好的函数的调用,把需要返回的内容传递进去
- 只能发送get请求,不安全,不好维护
- 兼容性比较好
- 打包工具自带的服务器代理请求,解决跨域
- 原理:跨域是浏览器特有的,而服务器和服务器之间不存在跨域。
- 后端解决
- 只要后端在响应头中加上对应的字段,浏览器就不会再报错。
- nginx服务器代理解决跨域
- jsonp
9.如果你接到一个项目如何从头开始的(需求,技术选型,技术环境,依赖哪些组件)
10.js的继承(口述代码)
js中的继承主要基于原型链(Prototype chain)
- 原型链继承:通过将子类的原型对象指向父类的实例,实现属性和方法的继承
- 借用构造函数继承:在子类构造函数中调用父类构造函数,通过call或apply绑定this
- 结合原型链继承和构造函数继承
- 原型式继承:基于已有对象创建新对象,通过Object.create()实现
- 寄生组合继承:通过借用构造函数继承属性,通过原型链混成形式继承方法「最优」
- class继承:extends+super(),语法糖,底层基于寄生组合式继承
11.闭包(闭包有什么缺点)
闭包让你可以在一个内层函数中访问到其外层函数的作用域。在js中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁。
闭包的使用场景:
- 创建私有变量
- 延长变量的生命周期
柯里化函数: 柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用
缺点:内存泄露。
当它引用了大量数据或长时间维持对外部作用域变量的引用,阻止了垃圾回收机制回收不再使用的内存空间。因为每次清理函数的执行上下文时,有被内部函数调用的变量,导致还留有一些变量在内存中,这就是闭包,当数据量太大的时候,闭包较多,而调用栈的容量有限,大量的闭包导致栈满或使得调用栈的可用内存变小了,这就是内存泄漏。
解决内存泄露的方法:
- 手动释放闭包的引用:在闭包不再需要访问外部变量时,显式地将闭包或者外部变量设置为null。这样可以断开闭包对外部作用域变量的引用,使得垃圾回收机制能够回收这些变量占用的内存。
- 事件处理和定时器清理:确保为所有的事件监听器和定时器设置清除机制,避免它们长时间持有闭包和相关的外部变量。
12.js的作用域有哪些 安全隐患
- 全局作用域:任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问
- 函数作用域:也叫局部作用域,如果一个变量在函数内部声明的,它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问
- 块级作用域:ES6中引入了let和const关键字,在大括号中使用let和const声明的变量存在于块级作用域中。在大括号之外不能访问这些变量
作用域链:
- 当在javascript中使用一个变量的时候,首先javascript引擎会尝试在当前作用域下去寻找改变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到改变量或是已经到了全局作用域
- 如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错
- 把作用域比喻成一个建筑,这份建筑代表程序中的嵌套作用域链,第一层代表当前的执行作用域,顶层代表全局作用域
- 变量的引用会顺着当前楼层进行查找,如果找不到,则会往上一层找,一旦到达顶层,查找的过程都会停止