实现一个 JS 函数, 功能是从数组中随机取一个元素
function getRandomElement(arr) {
if (!Array.isArray(arr) || arr.length === 0) {
return null;
}
const randomIndex = Math.floor(Math.random() * arr.length);
return arr[randomIndex];
}
iterator 和 数组 有什么关系
在 JavaScript 中,Iterator(迭代器)和数组有着密切的关系:
一、数组作为可迭代对象
-
可在迭代场景中使用:
- 数组是一种内置的可迭代对象,这意味着它可以在需要可迭代对象的地方使用,比如在
for...of循环、扩展运算符(...)和Array.from()等方法中。 - 例如:
- 数组是一种内置的可迭代对象,这意味着它可以在需要可迭代对象的地方使用,比如在
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item);
}
-
实现了迭代协议:
- 数组实现了可迭代对象的协议,即拥有一个
Symbol.iterator方法。这个方法返回一个 Iterator 对象,用于遍历数组的元素。
- 数组实现了可迭代对象的协议,即拥有一个
二、Iterator 用于遍历数组
-
提供遍历机制:
- Iterator 对象为数组的遍历提供了一种标准化的方式。通过调用数组的
Symbol.iterator方法获取 Iterator 对象,然后可以使用next()方法逐个访问数组的元素。 - 例如:
- Iterator 对象为数组的遍历提供了一种标准化的方式。通过调用数组的
const arr = [4, 5, 6];
const iterator = arr[Symbol.iterator]();
let result = iterator.next();
while (!result.done) {
console.log(result.value);
result = iterator.next();
}
某些数组方法利用 Iterator:
-
一些数组方法,如
forEach()、map()、filter()等,内部实际上是使用 Iterator 来遍历数组的元素。 -
例如,
map()方法创建一个新数组,其中每个元素都是对原始数组中对应元素调用提供的函数的结果:
const arr = [7, 8, 9];
const newArr = arr.map((item) => item * 2);
console.log(newArr);
HTTPS 安全协议主要是啥
一、加密通信
-
TLS/SSL 加密:
- HTTPS 使用传输层安全(TLS)或安全套接层(SSL)协议对数据进行加密。这确保了在客户端(如浏览器)和服务器之间传输的数据是经过加密的,防止数据被窃听、篡改或劫持。
- 加密过程通过使用对称加密算法(如 AES)和非对称加密算法(如 RSA)的组合来实现。在连接建立阶段,使用非对称加密算法交换对称密钥,然后使用对称密钥进行后续的数据加密和解密,以提高效率。
-
数据完整性保护:
- HTTPS 还使用消息认证码(MAC)来确保数据的完整性。接收方可以通过验证 MAC 来确定数据在传输过程中是否被篡改。如果 MAC 验证失败,接收方将拒绝接收数据,从而防止恶意篡改的数据被接受。
二、身份验证
-
服务器身份验证:
- HTTPS 通过服务器提供的数字证书来验证服务器的身份。数字证书由证书颁发机构(CA)签发,包含服务器的公钥和其他身份信息。
- 客户端在连接到服务器时,会验证服务器证书的真实性。这包括检查证书的颁发机构是否可信、证书是否在有效期内以及证书中的域名是否与服务器的域名匹配等。如果证书验证失败,客户端可能会显示警告或拒绝连接。
-
客户端身份验证(可选) :
- 在某些情况下,HTTPS 也可以用于客户端身份验证。例如,在企业内部网络或金融交易等场景中,服务器可能要求客户端提供数字证书或其他身份验证信息,以确保只有授权的用户可以访问资源。
三、安全连接建立
-
握手过程:
- HTTPS 的连接建立过程包括一个称为“握手”的阶段。在握手过程中,客户端和服务器交换信息,协商加密算法、密钥交换方式和其他安全参数。
- 这个过程确保双方都支持相同的安全协议版本,并能够建立一个安全的连接。握手过程还包括服务器身份验证和密钥交换,为后续的数据传输做好准备。
-
安全参数协商:
- 在握手过程中,客户端和服务器协商各种安全参数,如加密算法、密钥长度、MAC 算法等。双方选择最强的安全配置,以确保通信的安全性。
- 这个协商过程是动态的,可以根据客户端和服务器的能力以及安全需求进行调整。
前端如何快速获取页面 url query 参数
在前端,可以通过以下几种方式快速获取页面 URL 的查询参数:
一、使用 URLSearchParams API
-
基本用法:
-
URLSearchParams是一个内置的 JavaScript API,用于处理 URL 的查询参数。它提供了一种方便的方式来获取、设置和删除查询参数。 -
首先,可以使用
window.location.search获取 URL 的查询字符串,然后将其传递给URLSearchParams构造函数来创建一个URLSearchParams对象。 -
例如:
-
const urlParams = new URLSearchParams(window.location.search);
-
获取单个参数值:
- 可以使用
get方法来获取指定参数的值。例如,要获取名为paramName的参数值,可以使用以下代码:
- 可以使用
const paramValue = urlParams.get("paramName");
二、手动解析查询字符串
-
基本思路:
-
如果不使用
URLSearchParams,也可以手动解析 URL 的查询字符串。首先,获取window.location.search,它包含了查询字符串(例如?param1=value1¶m2=value2)。 -
然后,可以使用字符串的分割和遍历操作来提取参数名和参数值。
-
const queryString = window.location.search.substring(1);
const params = {};
const paramPairs = queryString.split("&");
paramPairs.forEach((pair) => {
const [key, value] = pair.split("=");
if (key) {
params[key] = decodeURIComponent(value);
}
});
vue3 对虚拟 dom 做了哪些优化
-
静态提升(Static Hoisting):Vue 3 在编译阶段会分析组件的模板,将静态的节点提升到渲染函数之外。这样在每次渲染时,不需要为静态节点创建新的虚拟 DOM 节点,从而减少了虚拟 DOM 的创建和比较开销。
- 例如,如果一个组件的模板中有一些静态的文本节点或元素,Vue 3 会在编译时将这些静态节点提取出来,在渲染时直接复用,而不是每次都重新创建虚拟 DOM 节点。
-
补丁算法优化:Vue 3 对虚拟 DOM 的补丁算法进行了优化,使得在更新 DOM 时更加高效。新的补丁算法可以更快地找到需要更新的节点,减少不必要的比较和操作。
- 比如,在对比新旧虚拟 DOM 树时,Vue 3 可以更准确地判断节点的类型和属性变化,只对真正发生变化的节点进行更新,提高了渲染性能。
-
事件处理优化:在 Vue 3 中,事件处理也进行了优化。对于静态的事件监听器,同样会在编译阶段进行提升,减少了每次渲染时的创建和绑定开销。
- 例如,如果一个组件中有一个静态的点击事件监听器,Vue 3 会在编译时将这个事件监听器提取出来,在渲染时直接复用,而不是每次都重新绑定。
如何计算页面白屏时间
白屏时间是指从浏览器开始请求页面到页面开始显示内容的时间。可以通过以下方法计算白屏时间:
一、使用浏览器的性能 API
现代浏览器提供了performance对象,可以用来获取页面加载过程中的各种时间戳。通过这些时间戳的差值可以计算出白屏时间。
-
具体步骤:
- 在页面的
<head>标签中插入一段 JavaScript 代码,在页面加载时记录关键时间点。 - 使用
performance.timing.navigationStart表示浏览器开始导航的时间戳。 - 寻找一个表示页面开始有内容显示的时间点,通常可以使用
performance.timing.domInteractive(文档被解析完成,开始加载外部资源时的时间戳)或者performance.timing.domContentLoadedEventStart(DOMContentLoaded事件开始的时间戳)作为近似的白屏结束时间点。 - 白屏时间 = 白屏结束时间点 -
performance.timing.navigationStart。
- 在页面的
如何计算页面首屏时间
页面首屏时间是指从浏览器开始请求页面到页面的首屏内容完全显示的时间。以下是几种计算首屏时间的方法:
一、使用浏览器性能 API 和自定义事件
-
具体步骤:
-
在页面的
<head>标签中插入一段 JavaScript 代码,在页面加载时记录浏览器开始导航的时间戳,即performance.timing.navigationStart。 -
当页面的首屏内容加载完成时,触发一个自定义事件。可以通过监听特定元素的加载完成或者使用特定的标志来判断首屏内容是否加载完成。
-
在自定义事件的处理函数中,获取当前时间戳,并减去开始导航的时间戳,得到首屏时间。
-
前端如何处理一个页面多主题色可供选择的场景
在前端处理一个页面有多个主题色可供选择的场景,可以通过以下几种方式实现:
一、使用 CSS 变量
-
定义 CSS 变量:
- 在 CSS 中,可以使用
--来定义变量。例如,可以定义一些代表主题色的变量:
- 在 CSS 中,可以使用
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
}
- 这里定义了两个变量
--primary-color和--secondary-color,分别代表主色和辅助色。
-
在 CSS 中使用变量:
- 然后在 CSS 规则中使用这些变量:
.button {
background-color: var(--primary-color);
color: white;
}
- 在这个例子中,
.button类的按钮背景颜色使用了--primary-color变量定义的颜色。
-
在 JavaScript 中切换主题:
- 在 JavaScript 中,可以通过修改
document.documentElement.style来改变 CSS 变量的值,从而切换主题色:
- 在 JavaScript 中,可以通过修改
const setTheme = (theme) => {
document.documentElement.style.setProperty("--primary-color", theme.primaryColor);
document.documentElement.style.setProperty("--secondary-color", theme.secondaryColor);
};
const theme1 = {
primaryColor: "#007bff",
secondaryColor: "#6c757d",
};
const theme2 = {
primaryColor: "#ff5733",
secondaryColor: "#999999",
};
// 切换到主题 1
setTheme(theme1);
// 切换到主题 2
setTheme(theme2);
- 在这个例子中,
setTheme函数接受一个主题对象,然后通过document.documentElement.style.setProperty方法修改 CSS 变量的值。可以定义多个主题对象,然后根据用户的选择切换主题。
二、使用预处理器(如 Sass、Less)
-
定义变量和混合:
- 在 Sass 或 Less 中,可以定义变量来代表主题色。例如,在 Sass 中:
$primary-color: #007bff;
$secondary-color: #6c757d;
.button {
background-color: $primary-color;
color: white;
}
-
这里定义了变量
$primary-color和$secondary-color,并在.button类中使用了这些变量。 -
创建多个主题文件:
- 可以创建多个主题文件,每个文件定义不同的变量值。例如,创建
theme1.scss和theme2.scss两个文件,分别定义不同的主题色。
- 可以创建多个主题文件,每个文件定义不同的变量值。例如,创建
-
在 JavaScript 中切换主题文件:
-
在 HTML 中,可以通过
<link>标签引入不同的 CSS 文件来切换主题。在 JavaScript 中,可以动态地修改<link>标签的href属性来切换主题文件:
-
const setTheme = (theme) => {
const link = document.getElementById("theme-link");
link.href = theme.href;
};
const theme1 = {
href: "theme1.css",
};
const theme2 = {
href: "theme2.css",
};
// 切换到主题 1
setTheme(theme1);
// 切换到主题 2
setTheme(theme2);