1、flex布局
Flex 布局(Flexible Box Layout)是一种用于页面布局的 CSS3 弹性盒子布局模型。它通过为父元素设置 display: flex;
,将其内部的子元素组织成一个灵活的容器,可以实现自适应和响应式的布局效果。
Flex 布局主要使用以下几个关键属性:
display: flex;
:将容器设置为一个 Flex 容器,用于容纳子元素。flex-direction: row | row-reverse | column | column-reverse;
:定义了主轴的方向,默认为横向,即row
,也可以设置为纵向,即column
。flex-wrap: nowrap | wrap | wrap-reverse;
:定义了子元素在一行(主轴上)排不下时如何换行,默认不换行,即nowrap
。justify-content: flex-start | flex-end | center | space-between | space-around;
:定义了子元素沿着主轴上的对齐方式。align-items: flex-start | flex-end | center | baseline | stretch;
:定义了子元素沿着交叉轴上的对齐方式。align-content: flex-start | flex-end | center | space-between | space-around | stretch;
:定义了多行子元素沿着交叉轴上的对齐方式。
子元素可以通过以下属性进行灵活布局:
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];
:定义了子元素的伸缩比例、收缩比例和基础宽度。align-self: auto | flex-start | flex-end | center | baseline | stretch;
:定义了单个子元素沿着交叉轴上的对齐方式,优先级高于父容器的align-items
属性。
Flex 布局的优点是可以快速实现各种复杂的页面布局效果,尤其适合移动端和响应式网页设计。但对于较老的浏览器可能不支持 Flex 布局。
2、position定位:fixed、relative和absoluted区别
属性 | 固定定位(fixed) | 相对定位(relative) | 绝对定位(absolute) |
定位方式 | 相对于浏览器窗口固定位置 | 相对于元素原来位置进行偏移 | 相对于最近的已定位祖先元素进行偏移 |
脱离文档流 | 是 | 否 | 是 |
可以使用的偏移属性 | top, right, bottom, left | top, right, bottom, left | top, right, bottom, left |
可以使用的z-index属性 | 是 | 否 | 是 |
元素的位置 | 固定不变 | 原来位置加上偏移量 | 原来位置加上偏移量 |
对父元素的影响 | 无 | 无 | 不改变前后元素对父元素布局的影响 |
元素过大时是否会被裁剪 | 否 | 否 | 是 |
固定定位(fixed)是相对于浏览器窗口视口的位置进行固定定位,不随滚动而移动,可以使用 top、right、bottom 和 left 属性进行偏移定位。常用于实现固定的导航栏或悬浮的元素。
相对定位(relative)是相对于元素原来的位置进行偏移定位,不会脱离文档流,仍会占据原来的位置,通过 top、right、bottom 和 left 属性进行定位。常用于微调元素的位置。
绝对定位(absolute)是相对于最近的已定位祖先元素进行偏移定位,或者如果没有已定位的祖先元素,则相对于浏览器窗口进行偏移定位。通过 top、right、bottom 和 left 属性进行定位。绝对定位的元素会脱离文档流,不会占据原来的位置。常用于实现页面布局中的定位元素。
对于父元素的影响方面,固定定位和相对定位不会影响父元素的布局,而绝对定位可能会改变前后元素对父元素的布局影响。
需要注意的是,使用绝对定位时,还可以通过设置 z-index 属性来控制元素的堆叠顺序,使叠加元素的层级关系正确展示。同时,当元素过大时,固定定位和相对定位不会被裁剪,而绝对定位会根据父元素的大小进行裁剪。
3、js数据类型,Symbol是什么、有什么用
在 JavaScript 中,数据类型主要包括以下几种:
- 基本数据类型:
- 数字(Number):表示数值(整数和浮点数)。
- 字符串(String):表示文本。
- 布尔值(Boolean):表示真或假。
- 空值(Null):表示一个空的或不存在的值。
- 未定义(Undefined):表示未赋值的变量。
- 大整数(BigInt):表示任意精度的整数。
- 引用数据类型:
- 对象(Object):一组键值对的集合,可以通过对象的属性(键)来访问对应的值。
- 数组(Array):一组有序的值的集合,通过索引(从 0 开始)来访问对应的值。
- 函数(Function):一段可执行的代码块,可以接受参数,并返回一个值。
- 日期(Date):表示一个日期和时间。
- 正则表达式(RegExp):用于匹配和处理字符串。
Symbol 是 ECMAScript6 新增的一种基本数据类型,用于表示唯一的标识符。每个由 Symbol 创建的值都是唯一的,不会与其他任何值相等,可以用作对象属性的键,防止键名冲突。
使用 Symbol 可以创建一个唯一的标识符,例如:
let sym1 = Symbol(); let sym2 = Symbol("description"); let sym3 = Symbol("description"); console.log(sym1); // Symbol() console.log(sym2); // Symbol(description) console.log(sym3); // Symbol(description) console.log(sym2 === sym3); // false
Symbol 可以用作对象的属性键,可以防止键名冲突的问题,例如:
let obj = { [sym1]: "value" }; console.log(obj[sym1]); // value
另外,Symbol 还有一些内置的属性和方法,例如 Symbol.iterator、Symbol.toStringTag 等,可以用于自定义对象的行为。Symbol 的引入提供了一种更灵活和安全的键生成方式,增加了 JavaScript 语言的表达能力。
4、ES6新增哪些API
ES6(ECMAScript 6)引入了许多新的 API(应用程序编程接口)和功能来增强 JavaScript 语言的能力。
下面是一些 ES6 中新增的主要 API:
- 块级作用域变量声明:使用
let
和const
关键字来声明块级作用域的变量。 - 模板字面量:使用反引号(`)来创建多行字符串,并包含变量的插入。
- 箭头函数:使用箭头(=>)来定义函数,以简化函数的编写和语法。
- 默认参数:允许在函数定义中为参数提供默认值。
- 参数解构赋值:可以通过解构赋值从数组或对象中提取值,并将其赋给变量。
- 类和继承:引入了类和继承的概念,以更简洁和面向对象的方式来创建对象。
- 模块化导入和导出:使用
import
和export
关键字来实现模块之间的依赖管理和代码复用。 - 迭代器和生成器:引入了迭代器和生成器的概念,用于简化迭代和异步编程模式。
- Promise 对象:用于处理异步编程,避免了回调函数地狱,提供了更直观和可靠的处理方式。
- Symbol 类型:新增了一种基本数据类型 Symbol,用于表示唯一的标识符。
- Set 和 Map 数据结构:引入了 Set 和 Map 两种新的数据结构,用于存储唯一的值和键值对。
- Proxy 和 Reflect 对象:Proxy 对象用于拦截并定义对象的基本操作,Reflect 对象提供了一组静态方法来操作对象。
- 数组的新方法:引入了一些方便的数组方法,如
find
、findIndex
、includes
等。 - 字符串的新方法:引入了一些方便的字符串方法,如
startsWith
、endsWith
、padStart
、padEnd
等。
这些是 ES6 中新增的一些主要 API,它们扩展了 JavaScript 的语法和功能,使得编写和维护代码变得更加简单和可靠。
5、TCP四次挥手
TCP(传输控制协议)是一种面向连接的协议,用于在网络上可靠地传输数据。TCP 的四次挥手是指在 TCP 连接关闭时,双方结束数据传输并释放资源的过程。下面是 TCP 四次挥手的步骤:
- FIN 响应:一方(通常是发送方)发送一个带有 FIN(结束)标志的 TCP 报文段给另一方(通常是接收方),表示它想要关闭连接。
- ACK 确认:接收方收到 FIN 报文段后,发送 ACK(确认)报文段作为确认应答。该 ACK 报文段中的序列号是上一个报文段的序列号加 1。
- 关闭通知:接收方同样发送一个带有 FIN 标志的 TCP 报文段给发送方,表示它也想要关闭连接。
- ACK 确认:发送方接收到 FIN 报文段后,发送 ACK 报文段作为确认应答。
这样,每个方向都发送了一个 FIN 和接收到了一个 ACK,所以需要进行四次握手才能完成连接的关闭。其中,第一次和第二次握手是关闭连接的请求和确认,第三次和第四次握手是关闭连接的通知和确认。四次握手确保了双方都对连接的关闭有了明确的认可,并且释放了连接所占用的资源。
需要注意的是,在这个过程中,每个方向都可同时进行关闭,也就是双方可以同时发送 FIN 报文段。这是为了防止出现等待的情况,可以更快地关闭连接。
6、localStorage和sessionStorage,存储大小
localStorage
和sessionStorage
是HTML5提供的用于在客户端(浏览器)存储数据的API。
localStorage
和sessionStorage
的存储大小都是根据浏览器的实现有所不同。
对于localStorage
来说,它的存储大小通常是以MB
为单位,可以存储相对较大的数据。
而sessionStorage
的存储大小通常较小,具体大小可能因浏览器和操作系统而异,一般在几十KB到几百KB之间。
需要注意的是,这些限制仅是大致估计,实际存储大小还受到浏览器设置、设备性能以及其他因素的影响。在实际使用过程中,如果需要存储大量数据,最好进行数据分片或使用其他适合的数据存储方式。
7、跨域怎么解决(开发环境和生成环境)
在开发环境中,为了解决跨域问题,可以通过启用跨域资源共享(CORS)来实现。CORS是一种机制,允许服务器在响应头中添加一些特殊的HTTP头,以允许客户端跨域访问资源。可以在服务端的响应中添加以下头部信息:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Content-Type
这些头部信息指定了允许跨域的来源,允许的HTTP
方法以及允许的请求头。
在生成环境中,一般不会继续使用CORS
解决跨域问题,而是采用其他方式,如JSONP、代理、反向代理等。
JSONP是一种利用<script>
标签的src属性跨域请求资源的方式,但它只支持GET请求。
使用代理,可以在同一域名下通过服务器转发请求,来解决跨域问题。前端发送请求给同域名的服务器,再由服务器发起跨域请求。
反向代理则是将前端请求通过服务器转发到目标服务器,目标服务器将响应返回给服务器,再由服务器返回给前端,这样前端可以通过同域名来获取跨域资源。
需要根据具体的情况选择合适的解决方案,以确保安全和稳定性。
8、跨域是浏览器的行为吗
是的,跨域是浏览器的安全策略之一,用于保护用户信息和防止恶意攻击。跨域限制是浏览器实施的,默认情况下,浏览器限制了从一个源(域、协议、端口)发送的请求访问另一个源的资源。这种限制被称为同源策略(Same-Origin Policy)。
浏览器执行跨域限制,是为了阻止恶意网站通过跨域请求来获取用户的敏感信息,或者利用跨域漏洞进行攻击。同源策略要求请求和资源必须具有相同的协议、域名和端口。
在跨域请求时,浏览器会发送一个预检请求(OPTIONS请求),将请求信息发送给目标服务器,目标服务器检查预检请求,返回合适的响应头,浏览器根据响应头判断是否允许跨域请求
。如果目标服务器返回适当的头部,浏览器才会发送真实的跨域请求。
需要注意的是,跨域限制仅存在于浏览器端,对于除了浏览器以外的客户端程序,如服务器端、命令行工具等,是不存在跨域限制的。
9、除了状态管理库(redux等)、组件间通讯还有其他什么方法
除了状态管理库(如redux)和组件间通信,还有以下一些方法可以实现组件间的数据传递和通信:
Props
:通过将数据作为属性传递给子组件,子组件就可以在其 props 属性中接收并使用这些数据。Context
:Context 允许在组件树中共享数据,这样可以避免将数据通过每个组件手动传递。但是,在大型项目中,使用 Context 可能会导致代码复杂性增加,建议慎用。- 事件:通过在父组件中定义一个回调函数,并将其作为 prop 传递给子组件,子组件可以通过调用该回调函数来触发事件并传递数据。
- 发布/订阅模式:使用 Pub/Sub 模式,可以在组件之间进行发布和订阅事件,组件可以通过订阅感兴趣的事件来接收数据,以实现组件间的通信。
- 全局变量:在某些情况下,可以使用全局变量来实现组件间的数据共享。但是,过度使用全局变量可能导致代码的可维护性和可测试性降低,因此需要慎重使用。
需要根据具体的需求和项目架构选择合适的方法。