前端面试题复盘

短期项目面试题

3-15号面试题复盘(问题都在目录中,答案点击相应的目录查看即可)

css怎么实现垂直居中

  1. Flexbox居中
    使用CSS Flexbox布局可以轻松实现水平和垂直居中
.container{
	display: flex;
	justify-content: center;/*水平居中*/
	align-items:center;/*垂直居中*/
}
<div class="container">
	<div class="content">内容</div>
</div>
  1. Grid居中
    CSS Grid也是提供了简单的居中方式
.container{
	display: grid;
	place-items: center; /*水平垂直居中*/
}
<div class="container">
	<div class="content">内容</div>
</div>
  1. 绝对定位和transform
    使用绝对定位和CSS transfrom 属性可以实现居中,但需要知道子元素的宽度和高度
.container{
	position: relative;
}
.content{
	position:absolute;
	top: 50%;
	left: 50%;
	transform:translate(-50% , -50%); /*水平垂直居中*/
}
<div class="container">
	<div class="content" style="width:200px; height:100px;">内容</div>
</div>
  1. text-align和line-height
    对于行内元素或单行文本,可以使用text-align和line-height属性实现水平和垂直居中
.container{
	text-align:center; /*水平居中*/
	line-height: 200px; /*假设容器高度为200px*/
	height:200px;/*垂直居中*/
	overflow: hidden; /*隐藏溢出的部分*/
}
<div class="container">
	<div class="content">内容</div>
</div>
  1. table-cell
    使用表格单元格布局可以实现居中,但是这种方式比较古老, 且在现代布局中使用较少
.container{
	display: table-cell;
	text-align: center; /*水平垂直居中*/
	vertical-align: middle;
}
<div class="container">
	<div class="content">内容</div>
</div>
  1. 其他方法
    还有一些其他方式,如使用padding或border来调整元素位置,但这些方法通常不如上述方法灵活和通用。
    选择哪种居中方法取决于具体的布局需求和兼容性要求。flexbox和Grid是现代布局中推荐的居中方法,因为它们提供了强大的布局能力,且易于理解和维护。

跨域怎么实现

跨域(Cross-Origin Resource Sharing, CORS)是浏览器中的一种安全举止,他限制了不同源(协议、域名、端口)之间的资源共享。为了实现跨域请求,可以采取以下几种常见方法:

1. CORS头部设置
服务器可以通过设置http响应头来允许跨域请求。以下是一些重要的cors头部:

  • Access-Control-Allow-Origin:指定哪些源可以访问资源。可以设置为具体某个域名,或者*表示允许任何源。
  • Access-Control-Allow-Methods:指定允许的http方法(如GET,POST,PUT,DELETE等)
  • Access-Control-Allow-Headers:指定允许的http请求头
  • Access-Control-Allow-Credentials:设置true时,允许携带认证信息(如cookies)

2. JSONP

JSONP(JSON with Padding)是一种利用<script>标签不受同源策略限制的特定性来实现跨域请求的技术。服务器返回的响应是一个函数调用,包裹着请求的数据。

3. 代理服务器

在服务器设置一个代理服务器,所有的客户端请求先发送到代理服务器,由代理服务器转发请求到目标服务器,并将响应返回给客户端。这样,客户端和代理服务器之间不会有跨域问题。

4.跨域资源共享(CORS)插件

在浏览器中按装CORS插件,如Chrome的CORS插件,可以临时绕过CORS限制,用于开发和测试。

5. WebSockets

对于实时通信,可以使用WebSockets协议,它不受同源策略的限制

6. postMessage API

这是HTML5中引入的一种安全的跨域通信方式,可以用于不同源之间的窗口通信,或者在不同的iframe之间传递消息。

7. Document.domain

如果两个页面的主域相同(例如 example.com和example2.com),可以通过设置document.domain='example.com’来实现跨域访问。

8. 用户代理脚本

用户可以在浏览器中按装脚本来修改http请求,添加必要的CORS头部,从而绕过跨域限制,这种方式需要用户手动参与。

实际应用实例
假设你需要从example.com发起一个跨域请求到api.example2.com,你可以在api.example2.com的服务器上设置CORS头部:

Access-Control-Allow-Origin:http://example.com
Access-Control-Allow-Methods: GET,POST,OPTIONS,DELETE
Access-Control-Allow-Headers: Content-Type
Access=Control-Allow-Credentials:true

在客户端,你可以直接发起AJAX请求:

fetch('http://api.example2.com/data',{
	method:'GET',
	headers:{
		'Content-Type': 'application/json'
	}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error',error));

Cookie,Session,LocalStorage的区别是什么

Cookie 、Session、和localStorage是web开发中常用的客户端存储技术,他们用于在用户和服务器之间保持状态或数据,尽管他们的目的相似,但是它们在存储位置、生命周期、容量和使用场景方面有所不同:
Cookie:

  1. 存储位置: 存储在客户端浏览器中,
  2. 生命周期: 可以设置过期时间,过期自动删除;如果没有设置过期时间,那么在浏览器回话结束时(用户关闭浏览器)删除。
  3. 容量限制: 大小限制在4kb左右
  4. 安全性: 敏感信息(如密码)不应存储在cookie中,因为它们可以被客户脚本(如JavaScript)访问
  5. 跨域: cookie可以设置为与域名相关联,也可以设置为路径相关联,但默认情况下,cookie至于创建它的域相关联
  6. 使用场景: 主要用于会话管理、个性化设置、跟踪用户等。

Session:
1. 存储位置: Session可以存储在客户端(作为Cookie,通常是SessionID)或者服务器端
2. 生命周期: session的生命周期通常用于与用户的浏览器会话相关联,但也可以设置特定的过期时间
3. 容量限制: 没有固定的容量限制,取决于服务器的配置和资源
4. 安全性: session本身存储在服务器端,相对安全,但是传输过程中的session id 需要保护,可以防止会话劫持。
5. 跨域: session id 通常通过cookie存储在客户端,因此受cookie的跨域策略影响。
6. **使用场景:**用于服务器端会话管理,如登录验证、购物车管理等。


LocalStorage
1. **存储位置:**存储在客户端浏览器中,特定某个域名
2. 生命周期: 数据持久存在,直到被明确删除或浏览器清除数据。
3. 容量限制: 容量限制大约为5mb
4. 安全性: :虽然数据只存储在客户端,但它们可以被任何同源JavaScript代码访问,因此敏感信息谨慎存储。
5. **跨域:**使用localstorage是同源的,不同域名之间不能访问彼此的localstorage数据。
6. 使用场景: 用于存储不敏感的的本地数据,如用户偏好设置、离线应用的数据存储等。


总结对比:

  • Cookie适用于需要在服务器和客户端之间共享的小型数据,如会话管理
    Session适用于服务器端的会话管理,可以存储更大的数据量,但需要服务器资源
    LocalStorage适用于客户端的持久化数据存储,不需要跨域共享,且不涉及服务器端的存储。

节流中重绘的出发条件

节流(Throttling)是一种优化技术,用于控制时间触发的频率。在前端开发中,尤其是在处理窗口缩放、滚动时间或高频触发的事件(如resize、scroll)时,节流可以减少不必要的计算和重绘,从而提高性能。

节流的重绘出发条件通常基于以下几个原则:

  1. 时间间隔: 节流函数会设置一个最小时间间隔,只有当两次触发的时间间隔超过这个设定值时,事件处理函数也只会每100毫秒执行一次。
    2.**请求动画帧(RequestAnimationFrame)😗*在某些情况下,开发者可能会选择使用requestAnimationFrame来作为节流的触发条件。这意味着事件处理函数会在浏览器的下次重绘之前执行,这样可以确保事件处理函数的执行与浏览器的渲染周期同步。
    3.**事件完成:**在某些节流实现中,事件处理函数会在事件停止触发后的最后一个事件间隔后执行。例如,如果用户停止滚动,节流函数会在最后一次事件滚动后的设定时间间隔后执行处理函数。
    4.**条件触发:**有时候,截留函数会根据特定的条件来决定是否执行事件处理函数。例如,只有当滚动距离超过一定阈值时,才会触发重绘。

以下时一个简单的节流函数实现示例,使用时间间隔作为触发条件:

function throttle(func,delay){
	let inThrottle;
	return function(){
		const context = this;
		const args = arguments;
		if (!inThrottle){
			func.apply(context.args);
			inThrottle = true;
			setTimeout(()=> inThrottle = false,delay);
		}
	};
}
//使用
window.addEventListener('scroll',throttle(handleScroll,100));

在这个例子中,handleScroll函数会在滚动事件触发后的100毫秒内只执行一次,如果用户在100毫秒内连续滚动,handleScroll函数会等到滚动停止100毫秒后才会执行。
通过这种方式,节流可以有效的控制事件处理函数的执行频率,减少不必要的重绘和计算,从而优化页面的性能。

箭头函数和普通函数的区别

箭头函数(Arrow functions)是ES6引入的一种新的函数语法,它提供了一种更简洁的方式来编写函数表达式。箭头函数与普通函数(也成为传统函数或方法)在语法和功能上有一些显著的区别:
语法区别:

  • **箭头函数:**使用=>语法,更短的函数声明方式。
const myFunction = (param1,param2)=> {
	//函数体
	return param1 + param2;
};
  • **普通函数:**使用function关键字和圆括号包围参数。
function myFunction(param1,param2){
	//函数体
	return param1 + param2;
}

功能区别:

  1. this绑定:
    - 箭头函数不绑定自己的this,他们会捕获其所有上下文的this值,作为自己的this值。
    - 普通函数有自己的this绑定,this的值取决于函数的调用方式。
  2. arguments对象:
    - 箭头函数没有自己的arguments对象。
    - 普通函数有自己的argument对象,包含了函数调用时传入的所有参数。
  3. super关键字:
    - 箭头函数蹦年使用super关键字。
    - 普通函数可以正常使用super关键字,尤其时在构造函数中。
  4. new关键字和构造函数:
    - 箭头函数不能使用new关键字,不能作为构造函数
    - 普通函数可以使用new关键字创建实例,可以作为构造函数。
  5. 原型属性:
    - 箭头函数没有prototype属性。
    - 普通函数没有prototype属性,可以添加方法
  6. 方法定义:
    - 箭头函数不能使用prototype方法定义
    - 普通函数可以通过prototype方法定义方法
  7. 生成方法:
    - 箭头函数不能作为Generator函数使用, 不能使用yield关键字
    - 普通函数可以作为Generator函数,使用yield关键字。

使用场景:

  • 当你需要要给没有自己this绑定的函数时,获取需要一个更简洁的函数表达式时,箭头函数时一个好选择。
  • 当你需要使用new关键字、arguments对象、super关键字或者需要定义可枚举的属性时,应该使用普通函数。

for…in 和 for…of的区别

for…in 和 for…of是JavaScript中遍历集合(如数组、对象、Map、Set等)的两种不同的循环结构。它们在语法和使用场景上有一些关键的区别:

for…in循环:

  1. 遍历对象属性:
    for…in 用于遍历一个对象的所有可枚举属性(包括原型链上的属性)。
    const obj = {a:1,b:2};
    for (const key in obj){
    	console.log(key);//输出: ’a‘,'b'
    }
    
  2. 返回键名:
    for…in 循环变量得到的是对象属性的键名(key),而不是属性值。
  3. 不保证顺序:
    for…in 不保证属性的遍历顺序,通常按照插入顺序,但依赖于具体JavaScript引擎的实现。
  4. 不适用于迭代数组:
    for…in 循环不适用于数组,因为它会遍历数组的所有属性,包括可能的原型链上的属性,导致循环次数不可预测。

for…of循环:

  1. 迭代器协议:
    for…of用于遍历实现了迭代器协议的对象,如数组、Map、Set、字符串等。
    const arr = [1,2,3];
    for(const value of arr){
    	console.log(value);//输出:1,2,3
    }
    
  2. 返回值:
    for…of 循环变量得到的是集合中的当前值。
  3. 保证顺序:
    for…of 循环保证按照插入顺序遍历集合中的元素。
  4. 适用于数组:
    for…of循环是为数组设计的,可以安全的用于数组的遍历。

总结:

  • 如果你需要遍历一个对象的所有属性,使用 for…in
  • 如果你需要遍历一个集合的元素,特别是数组,使用for…of
  • for…of是更现代的语法,适用于ES6迭代器协议,通常推荐用于数组和其他可迭代对象的遍历。
  • for…in由于其限制和不稳定性,通常不推荐用于数组的遍历,但在遍历对象属性时仍然有用。

在使用for…in时,需要注意对象属性的枚举顺序可能会受到原型链的影响,因此在需要确定顺序的情况下,可能需要额外的逻辑来处理。而for…of则提供了一种更简洁、更安全的方式来遍历集合。

  • 15
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值