Open cristinazhou opened 1 year ago
npm 与 yarn 的区别
npm包的版本 '~4.5.6' 波浪线表示什么意思?
axios 添加多个拦截器 是怎么回事? 算法 : 树转数组
{
value: ‘1’,
label: '节点1’,
children: [
{
value: ‘2’,
label: '节点1-1’,
children: [
{
value: ‘3’, label: '节点1-1-1’
}
],
},
{
value: 4,
label: '节点1-2’,
}
]
}
转化成扁平的item Array
[
{ value: 1, label: '节点1' },
{ value: 2, parentId: 1, label: '节点1-1' },
{ value: 3, parentId: 2, label: '节点1-1-1' },
{ value: 4, parentId: 1, label: '节点1-2’ }
]
interface IArrayItem {
id: number;
name: string;
parentId: number;
}
interface ITreeNode {
id: number;
name: string;
children?: ITreeNode[];
}
function convert1(root: ITreeNode): IArrayItem[] {
// Map
const nodeToParent: Map<ITreeNode, ITreeNode> = new Map();
const arr: IArrayItem[] = [];
// 广度优先遍历,queue
const queue: ITreeNode[] = [];
queue.unshift(root); // 根节点 入队
while (queue.length > 0) {
const curNode = queue.pop(); // 出队
if (curNode == null) break;
const { id, name, children = [] } = curNode;
// 创建数组 item 并 push
const parentNode = nodeToParent.get(curNode);
const parentId = parentNode?.id || 0;
const item = { id, name, parentId };
arr.push(item);
// 子节点入队
children.forEach((child) => {
// 映射 parent
nodeToParent.set(child, curNode);
// 入队
queue.unshift(child);
});
}
return arr;
}
const obj = {
id: 1,
name: "部门A",
children: [
{
id: 2,
name: "部门B",
children: [
{ id: 4, name: "部门D" },
{ id: 5, name: "部门E", children: [{ id: 7, name: "部门G" }] },
],
},
{
id: 3,
name: "部门C",
children: [{ id: 6, name: "部门F" }],
},
],
};
const arr1 = convert1(obj);
console.info(arr1);
移动端适配,vw降级方案 vw 存在兼容问题,桌面PC中,vw兼容Chrome26、Firefox19、Safari6.1、IE10 和 Opera15以上版本; 移动设备中,vw兼容Andriod4.4和IOS8以上的版本。
降级处理不兼容 在我们已知的大部分主流浏览器中,都是天然支持vw单位的,但不排除有某些浏览器的某些版本存在不兼容的情况,如果业务需要,我们可以通过如下两种方式做降级处理:
• CSS Houdini:通过CSS Houdini针对vw做处理,调用CSS Typed DOM Level1提供的CSSUnitValue API; • CSS Polifill:通过相应的Polyfill做响应的处理,目前针对vw单位的Polyfill主要有:vminpoly、Viewport Units Buggyfill、vunits.js和Modernizr。大漠老师比较推荐的是Viewport Units Buggyfill
SSR存在的弊端 :
服务端需要准备好所有的组件的HTML才能返回。如果某个组件需要的数据耗时较久,就会阻塞整个HTML的生成。 Hydration 是一次性的,用户需要等待客户端加载所有组件的javascript并hydrated完成后才能和任一组件交互。 渲染逻辑复杂时,页面首次渲染到可交互之间存在较长的不可交互时间。 在React SSR中不支持客户端渲染常用的代码分割组合 React.lazy 和 Suspense。 在React 18中心的SSR架构React Fizz带来了阿玲哥主要新特性来解决上述缺陷。 Streaming HTML (流式渲染) 和 Selective Hydration (选择性注水)
一般来说,流式渲染就是把 HTML 分块通过网络传输,然后客户端收到分块后逐步渲染,提升页面打开时的用户体验。通常是利用HTTP/1.1中的分块传输编码(Chunked transfer encoding)机制。
label-loader 是怎么将 TypeScript 文件转换成标准 JavaScript 文件的呢?答案是直接删除掉类型注解。先看一下 babel 的工作流程,babel 主要有三个处理步骤:解析、转换和生成。
解析:将原代码处理为 AST。对应 babel-parse 转换:对 AST 进行遍历,在此过程中对节点进行添加、更新、移除等操作。对应 babel-tranverse。 生成:把转换后的 AST 转换成字符串形式的代码,同时创建源码映射。对应 babel-generator。
在加入@babel/preset-typescript 之后,babel 这三个步骤是如何运行呢
解析:调用 babel-parser 的 typescript 插件,将源代码处理成 AST。
转换:babel-tranverse 的过程中会调用 babel-plugin-transform-typescript 插件,遇到类型注解节点,直接移除。
生成:遇到类型注解类型节点,调用对应输出方法。其它如常。
使用 babel,不仅能处理 typescript,之前 babel 就已经存在的 polyfill 功能也能一并享受。并且由于 babel 只是移除类型注解节点,所以速度相当快。那么问题来了,既然 babel 把类型注解移除了,我们写 TypeScript 还有什么意义呢?我认为主要有以下几点考虑:
性能方面,移除类型注解速度最快。收集类型并且验证类型是否正确,是一个相当耗时的操作。 babel 本身的限制。本文第一节分析过,进行类型验证之前,需要解析项目中所有文件,收集类型信息。而 babel 只是一个单文件处理工具。Webpack 在调用 loader 处理文件时,也是一个文件一个文件调用的。所以 babel 想验证类型也做不到。并且 babel 的三个工作步骤中,并没有输出错误的功能。 没有必要。类型验证错误提示可以交给编辑器。
当然,由于 babel 的单文件特性,@babel/preset-typescript 对于一些需要收集完整类型系统信息才能正确运行的 TypeScript 语言特性,支持不是很好,如 const enums 等。完整信息可以查看文档。
作者:字节前端 链接:https://juejin.cn/post/7007251289721536543 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
HTML 标签 js手写题目 js 怎么检测一段html字符串 是否合法,标签是否是匹配的
function isHtmlStringValid(htmlString) {
const stack = []
const openingTagPattern = /<(\/?\w+)[^>]*>/g;
let match
while ((match = openingTagPattern.exec(htmlString)) !== null) {
const tagName = match[1]; // p /p
console.info('tagName', tagName)
if (tagName.includes('/')) {
const closingTag = tagName.replace('/', '');
if (stack.length === 0 || stack.pop() !== closingTag) {
return false;
}
} else {
stack.push(tagName);
}
}
return stack.length === 0;
}
// 示例用法:
const htmlString1 = '<p>Hello, <strong>world!</strong><a>1111</a></p>';
console.log(isHtmlStringValid(htmlString1)); // 输出: true
const htmlString2 = '<p>Hello, <strong>world!</p>';
console.log(isHtmlStringValid(htmlString2)); // 输出: false
提高HTTP请求得响应速度 1、CDN 2、DNS Prefetch 3、http2
减小资源大小 1、 代码压缩 2、图片压缩 3、代码拆分
优化资源加载时机 1、按需加载 2、懒加载 3、预加载
优化资源加载方式 1、客户端内H5 可考虑使用离线包 2、内容直出SSR
let url = https://github.com/cristinazhou/Blog/issues/5?a=%E5%8C%97%E4%BA%AC&b=1&b=3&c
解析成 object = {
a: '北京',// 中文解析 b: [ 1, 3], // 相同参数解析为数组 c: true // 没有值的参数 赋值为true }
function parseURL(url) { const queryIndex = url.indexOf('?'); const queryString = url.slice(queryIndex + 1);
const params = new URLSearchParams(queryString); const object = {};
for (const [key, value] of params.entries()) { if (value === '') { object[key] = true; } else { if (object.hasOwnProperty(key)) { if (Array.isArray(object[key])) { object[key].push(value); } else { object[key] = [object[key], value]; } } else { object[key] = decodeURIComponent(value); } } }
return object; }
// 示例用法: const url = 'https://github.com/cristinazhou/Blog/issues/5?a=%E5%8C%97%E4%BA%AC&b=1&b=3&c'; const parsedObject = parseURL(url); console.log(parsedObject);