前端热门面试题目——React、Node
img
标签的 srcset
属性的作用
srcset
属性允许开发者为不同设备或分辨率提供多个图像选项,优化加载的图片以适应设备的屏幕大小和分辨率。这提高了性能和用户体验。
示例:
<img src="default.jpg" srcset="small.jpg 480w, medium.jpg 1024w, large.jpg 1600w" sizes="(max-width: 600px) 480px, (max-width: 1200px) 1024px, 1600px" alt="Example image">
srcset
:定义图片文件及其宽度说明。例如,small.jpg 480w
表示small.jpg
的宽度为 480 像素。sizes
:定义显示图片的逻辑宽度条件,例如480px
表示当屏幕宽度小于 600px 时,选择 480px 的图片。
浏览器会根据设备的屏幕分辨率和宽度自动选择最合适的图片。
CSS 中可继承与不可继承属性有哪些
- 可继承属性:如字体相关的属性(font-family、font-size、font-weight等)、文本相关的属性(text-align、text-indent、line-height等)、颜色相关的属性(color)以及列表相关的属性(list-style-type、list-style-position等)。
- 不可继承属性:如盒子模型相关的属性(width、height、margin、padding、border等)、定位相关的属性(position、top、right、bottom、left、float、clear等)、显示和可见性相关的属性(display、visibility等)以及背景相关的属性(background-color、background-image等)。
如何计算 CSS 的优先级
CSS 的优先级计算基于选择器的类型和数量,具体规则如下:
- 内联样式(如style属性中的样式)的优先级最高。
- ID选择器(如#id)的优先级次于内联样式,但高于其他选择器。
- 类选择器(如.class)、属性选择器(如[type=“text”])和伪类选择器(如:hover)的优先级相同。
- 元素选择器(如div、p)和伪元素选择器(如::before、::after)的优先级最低。
此外,如果两个选择器的优先级相同,则后定义的样式会覆盖先定义的样式(即“后来者居上”原则)。同时,可以使用!important
声明来提高某个样式规则的优先级,使其高于其他任何非!important
的样式规则。但需要注意的是,过度使用!important
可能会导致样式表难以维护。
有哪些 CSS 选择器及其介绍
CSS 选择器用于选择需要应用样式的HTML元素,常见的CSS选择器包括:
- 元素选择器:选择HTML文档中的特定类型的元素(如
div
、p
等)。 - 类选择器:选择具有特定类属性的HTML元素(如
.myClass
)。类选择器前面有一个点号(.
)。 - ID选择器:选择具有特定ID属性的HTML元素(如
#myId
)。ID选择器前面有一个井号(#
),且ID在HTML文档中应该是唯一的。 - 属性选择器:选择具有特定属性的HTML元素(如
[type="text"]
)。属性选择器使用方括号[]
来包含属性名和可选的属性值。 - 伪类选择器:选择处于特定状态的HTML元素(如
:hover
、:first-child
等)。伪类选择器以冒号(:
)开头。 - 伪元素选择器:选择文档树中不存在的、但被CSS渲染为元素的部分(如
::before
、::after
等)。伪元素选择器以双冒号(::
)开头(CSS3规范),但在某些旧版浏览器中可能使用单冒号(:
)。 - 后代选择器:选择某个元素的后代元素(如
div p
,选择所有位于<div>
元素内的<p>
元素)。 - 子选择器:选择某个元素的直接子元素(如
ul > li
,选择所有直接位于<ul>
元素下的<li>
元素)。 - 相邻兄弟选择器:选择紧接在另一个元素后的兄弟元素(如
h1 + p
,选择紧接在<h1>
元素后的第一个<p>
元素)。 - 通用选择器:选择所有元素(如
*
)。
Canvas 和 SVG 的区别
Canvas和SVG都是用于在网页上绘制图形的技术,但它们有以下区别:
- 绘图方式:Canvas使用JavaScript来绘制图形,而SVG则是使用XML来描述图形。
- 图形质量:Canvas绘制的图形是像素级的,因此放大或缩小时可能会出现模糊。而SVG绘制的图形是矢量图形,无论放大或缩小都能保持清晰。
- 交互性:Canvas更适合用于需要频繁更新和重绘的图形,如游戏或动画。而SVG则更适合用于静态或较少变化的图形,如图标或图表。
- 兼容性:Canvas在大多数现代浏览器中都有良好的支持,而SVG在某些旧版浏览器中可能存在兼容性问题。
HTML 中,title 与 h1 标签的区别
- title标签:位于HTML文档的
<head>
部分,用于定义文档的标题。这个标题通常显示在浏览器的标签栏或标题栏上,并且也是搜索引擎在索引网页时使用的关键信息之一。 - h1标签:位于HTML文档的
<body>
部分,用于定义文档中最重要的标题或章节标题。在网页内容中,h1标签通常只使用一次,表示页面的主标题。h1标签对于搜索引擎优化(SEO)和网页的可读性都很重要。
HTML 行内元素、块级元素、空(void)元素
- 行内元素:不会独占一行,只占据其必要的宽度。常见的行内元素包括
<a>
(链接)、<span>
(文本容器)、<img>
(图像)、<br>
(换行符)等。 - 块级元素:会独占一行,并扩展到其父元素的整个宽度。常见的块级元素包括
<div>
(块级容器)、<p>
(段落)、<h1>
至<h6>
(标题)、<ul>
(无序列表)、<ol>
(有序列表)等。 - 空(void)元素:也称为自闭合元素或空标签,它们没有闭合标签,且通常没有内容。常见的空元素包括
<br>
(换行)、<hr>
(水平线)、<img>
(图像)、<input>
(输入字段)等。
HTML 的 src 和 href 属性
- src属性:通常用于
<img>
、<script>
、<video>
、<audio>
等标签中,指定资源(如图像、脚本文件、视频文件等)的路径。 - href属性:通常用于
<a>
、<link>
等标签中,指定链接目标的URL。在<a>
标签中,href属性定义了超链接的目标地址;在<link>
标签中,href属性则用于指定外部资源(如CSS文件)的路径。
什么是 HTML 语义化
HTML语义化是指根据内容的结构和含义(内容语义化),选择合适的HTML标签(代码语义化),以更好地表达内容的意义和层次。使用语义化标签可以让搜索引擎更容易理解网页内容,有利于搜索引擎优化(SEO);同时,语义化标签也有助于提高网页的可访问性,使屏幕阅读器等辅助技术能够更好地理解和朗读网页内容。此外,语义化标签还有助于提高代码的可读性和可维护性。
DOCTYPE(文档类型)的作用
DOCTYPE是HTML文档中的声明,用于指定HTML的版本和解析方式。DOCTYPE声明的目的是告诉浏览器应该使用哪种HTML或XHTML规范来解析文档。正确的DOCTYPE声明对于确保网页在浏览器中正确显示和渲染非常重要。如果缺少了DOCTYPE声明或者声明不正确,浏览器可能会以兼容模式(quirks mode)来解析文档,这可能会导致一些意料之外的布局和样式问题。
HTML 的 script 标签中 defer 和 async 有什么区别
在HTML的<script>
标签中,defer
和async
都是用于控制脚本加载和执行的属性,但它们有以下区别:
- defer属性:带有
defer
属性的脚本会异步加载,并在整个页面解析完成后、在DOMContentLoaded事件触发之前执行。这意味着,带有defer
属性的脚本会按照它们在HTML文档中出现的顺序执行。此外,defer
属性只适用于外部脚本(即带有src
属性的<script>
标签)。 - async属性:带有
async
属性的脚本也会异步加载,但一旦脚本加载完成,就会立即执行,而不等待整个页面解析完成。这意味着,带有async
属性的脚本可能会打乱页面中其他脚本的执行顺序。与defer
属性不同,async
属性适用于外部脚本和内联脚本(即不带有src
属性的<script>
标签)。
常用的 HTML meta 标签
常用的HTML meta标签包括:
<meta charset="UTF-8">
:定义文档的字符编码。<meta name="viewport" content="width=device-width, initial-scale=1.0">
:用于控制视口(viewport)的大小和缩放比例,以适应不同设备的屏幕尺寸。<meta name="description" content="网页描述内容">
:提供网页的描述信息,有助于搜索引擎索引和显示。<meta name="keywords" content="关键词1,关键词2,关键词3">
:提供网页的关键词信息,虽然现代搜索引擎对关键词标签的依赖程度较低,但仍然可以作为补充信息。<meta name="author" content="作者名">
:定义网页的作者信息。<meta name="robots" content="index,follow">
:控制搜索引擎对网页的索引和跟踪行为。
HTML5 相比于 HTML 的更新
HTML5是HTML的最新版本,相比于之前的HTML版本,它带来了许多新功能和改进,具体包括:
- 语义化标签:HTML5引入了大量语义化的标签,如
<header>
、<footer>
、<nav>
、<article>
、<aside>
等,这些标签使得HTML结构更加清晰,便于搜索引擎理解和用户阅读。 - 多媒体支持:HTML5直接支持
<video>
和<audio>
标签,无需插件即可播放多媒体内容。 - 表单增强:HTML5引入了许多新的表单元素和输入类型,如
<datalist>
、`’
1. 什么是 React 中的受控组件? 它的应用场景是什么?
-
受控组件:
受控组件是指 React 中通过组件的state
来管理表单元素(如<input>
、<textarea>
)的值,其值受组件state
控制。特点:
- 表单元素的值由
state
决定,受控于 React。 - 用户输入触发
onChange
事件,更新state
,从而引发组件重新渲染。
示例:
function ControlledInput() {const [value, setValue] = React.useState("");return (<inputtype="text"value={value}onChange={(e) => setValue(e.target.value)}/>); }
- 表单元素的值由
-
应用场景:
- 表单验证:实时验证用户输入,动态显示错误信息。
- 动态渲染:根据输入动态更新 UI,例如搜索功能。
- 统一管理数据:表单数据存储在组件
state
中,便于提交时统一处理。
2. 为什么 React 使用虚拟 DOM 来提高性能?
React 使用虚拟 DOM(Virtual DOM)提高性能的主要原因是优化了实际 DOM 的操作。
-
虚拟 DOM 工作原理:
- React 维护一个内存中的虚拟 DOM。
- 当组件状态或属性变化时,React 根据变化生成新的虚拟 DOM。
- React 对比新旧虚拟 DOM,计算出最小的变化(Diffing)。
- React 只更新必要的真实 DOM。
-
性能优势:
- 减少直接 DOM 操作:实际 DOM 操作昂贵,虚拟 DOM 在内存中处理效率更高。
- 批量更新:将多次 DOM 更新合并为一次操作。
- 跨平台:虚拟 DOM 是平台无关的,可以用于 Web、Mobile 等多种场景。
3. Redux 如何实现多个组件之间的通信?
-
Redux 的核心机制:
- 中央状态管理:Redux 使用一个全局的
store
保存状态。 - 单向数据流:
- 组件通过
dispatch(action)
触发状态更新。 - 状态更新后,
store
通知所有订阅的组件。
- 组件通过
- 订阅和更新:
- 组件使用
connect
(或useSelector
)从store
中读取状态。 - 状态变化时,订阅的组件会重新渲染。
- 组件使用
- 中央状态管理:Redux 使用一个全局的
-
多个组件通信的实现:
- 通过共享
store
状态。 - 组件 A 更新状态,组件 B 通过订阅获取更新后的状态。
- 通过共享
4. 多个组件使用相同状态时如何进行管理?
Redux 提供了集中式状态管理工具,通过以下方式管理多个组件的相同状态:
- 状态存储:
- 将多个组件需要共享的状态存储在
store
中。
- 将多个组件需要共享的状态存储在
- 拆分 Reducers:
- 使用
combineReducers
拆分逻辑,按模块组织状态。
- 使用
- 按需订阅:
- 组件使用
useSelector
选择需要的状态,避免不必要的重渲染。
- 组件使用
- 中间件:
- 使用中间件(如
redux-thunk
)处理异步逻辑,保持状态一致性。
- 使用中间件(如
5. 用户从输入网址到网页显示期间发生了什么?(从网络角度)
-
DNS 解析:
- 用户输入网址(如
www.example.com
),浏览器通过 DNS 解析获取服务器 IP 地址。
- 用户输入网址(如
-
建立 TCP 连接:
- 浏览器通过三次握手与服务器建立 TCP 连接。
-
发送 HTTP 请求:
- 浏览器向服务器发送 HTTP 请求,包含请求头和其他信息。
-
服务器处理请求:
- 服务器接收到请求后,处理逻辑并生成响应(如 HTML 文件)。
-
返回 HTTP 响应:
- 服务器返回包含内容的 HTTP 响应,可能包括 HTML、CSS、JS 和图片等。
-
浏览器渲染页面:
- 浏览器解析 HTML,构建 DOM 树。
- 解析 CSS,构建 CSSOM 树。
- 合并 DOM 和 CSSOM,生成渲染树。
- 根据渲染树进行布局和绘制。
-
执行 JS:
- 浏览器解析并执行 JavaScript,更新页面内容或行为。
-
加载资源:
- 浏览器根据 HTML 和 CSS 中的引用加载资源(如图片、字体等)。
-
页面展示:
- 浏览器将渲染的结果显示给用户。
React Router 的 history 模式中,push 和 replace 方法有什么区别?
在 React Router 的 history 模式中,push
和 replace
方法都用于在浏览历史记录中添加或更改条目,但它们有不同的行为:
-
push:将一个新条目推入历史堆栈中。这类似于用户点击浏览器中的链接或在新标签页中打开页面。当用户点击浏览器的后退按钮时,可以返回到前一个页面。
-
replace:用当前条目替换历史堆栈中的当前条目。这不会增加历史堆栈的长度。当用户点击浏览器的后退按钮时,他们将不会返回到被替换的页面,而是直接跳转到前一个存在的页面(如果存在)。
如果 React 组件的属性没有传值,它的默认值是什么?
如果 React 组件的属性(props)没有传值,那么该属性的值将是 undefined
。如果你希望为某个属性提供默认值,可以在组件内部使用逻辑运算符(如 ||
或 ??
)或解构赋值时的默认值来实现。
React 中除了在构造函数中绑定 this,还有其他绑定 this 的方式么?
是的,React 中除了在构造函数中绑定 this
,还有其他几种绑定 this
的方式:
- 箭头函数:在 JSX 中或组件的方法中使用箭头函数可以自动绑定
this
到当前组件实例。 - 类属性方法:在类定义中直接使用箭头函数作为方法(但请注意,这种方法在类字段提案被完全支持之前可能不是所有环境都可用)。
- 在事件处理程序中绑定:在将方法传递给事件处理程序时,可以在调用时绑定
this
(但这通常不推荐,因为它会在每次渲染时都创建一个新的函数实例)。 - 使用外部库(如
bind-decorator
):可以使用第三方库来简化this
的绑定过程。
为什么在 React 中遍历时不建议使用索引作为唯一的 key 值?
在 React 中,当使用列表渲染(如使用 map
方法遍历数组并返回 JSX 元素)时,每个元素都需要一个唯一的 key
属性来帮助 React 识别哪些元素是唯一的、哪些元素被修改、添加或删除了。虽然可以使用索引作为 key
,但这通常不是最佳实践,因为:
- 当列表项的顺序发生变化时,即使内容没有变化,使用索引作为
key
也会导致所有列表项重新渲染,因为索引已经改变了。 - 如果列表项可以被添加、删除或移动,使用索引作为
key
可能会导致状态管理上的问题,因为索引不再是稳定的标识符。
更好的做法是使用每个列表项的唯一标识符(如 ID)作为 key
。
React Router 中的 Router 组件有几种类型?
React Router 提供了几种不同类型的 Router
组件,以适应不同的应用场景:
- BrowserRouter:用于在支持 HTML5 历史 API 的环境中(如现代浏览器)提供 URL 的管理功能。它使用浏览器的历史记录堆栈来管理 URL 的变化。
- HashRouter:使用 URL 中的哈希(#)部分来管理历史记录。它适用于不支持 HTML5 历史 API 的环境(如旧版浏览器)或当你不希望服务器配置来支持干净的 URL 时。
- MemoryRouter:在内存中管理历史记录堆栈,不依赖于浏览器的 URL。它通常用于测试或服务器端渲染。
- StaticRouter:一个用于服务器端渲染的
Router
,它不会监听或修改 URL。它通常与ReactDOMServer.renderToString
一起使用。
在 React 的 render 函数中,是否可以直接写 if else 判断?为什么?
在 React 的 render
函数中,你不能直接写 JavaScript 的 if-else
语句,因为 JSX 需要返回有效的 React 元素或 null
,而 if-else
语句本身不返回这些值。但是,你可以在 render
方法中使用条件(三元)运算符、逻辑运算符或直接在 JSX 中嵌入表达式来实现条件渲染。
例如,你可以使用三元运算符:
render() {const isLoggedIn = this.state.isLoggedIn;return (<div>{isLoggedIn ? <LoggedInComponent /> : <LoginComponent />}</div>);
}
或者,你可以在 JSX 中使用逻辑与(&&
)运算符:
render() {const isLoggedIn = this.state.isLoggedIn;return (<div>{isLoggedIn && <LoggedInComponent />}{!isLoggedIn && <LoginComponent />}</div>);
}
如何在 React 项目中引入图片?哪种方式更好?
在 React 项目中引入图片有几种方式:
- 直接作为 JSX 中的
src
属性:你可以将图片文件放在项目的public
文件夹中,并在 JSX 中直接使用相对路径作为img
标签的src
属性。 - 使用
import
语句:你可以将图片文件作为模块导入,并在 JSX 中使用导入的变量作为src
属性。这种方法允许你使用 Webpack 等构建工具来处理图片(如压缩、优化等)。 - 使用 CSS/Sass 等预处理器:你可以将图片作为背景图像在 CSS/Sass 文件中引入。
通常,使用 import
语句来引入图片是更好的方式,因为它允许你利用构建工具的功能来优化图片,并且可以在代码中更容易地引用和管理图片资源。
在 React 的 JSX 中,属性是否可以被覆盖?覆盖的原则是什么?
在 React 的 JSX 中,属性(props)是可以被覆盖的,但覆盖的原则取决于属性的来源和组件的层次结构。
- 父组件传递给子组件的属性:当父组件将属性传递给子组件时,如果子组件在其 JSX 中为该属性提供了不同的值,则子组件中的值将覆盖父组件传递的值。
- 组件自身的默认属性:如果组件在其内部定义了默认属性,并且这些属性在 JSX 中被显式地设置了不同的值,则显式设置的值将覆盖默认值。
- 属性合并:对于某些属性(如
style
和className
),React 允许你通过对象合并的方式将它们组合在一起,而不是简单地覆盖。例如,你可以将父组件传递的style
对象与组件内部的style
对象合并在一起。
总的来说,属性覆盖的原则是基于属性的来源和组件的层次结构来确定的,并且 React 提供了一些机制来允许属性合并而不是简单的覆盖。
1. Node.js 中同步和异步代码的区别
-
同步代码:
- 按照代码的顺序执行,后续代码必须等待前面的代码执行完毕。
- 阻塞操作:执行期间会阻塞其他任务。
示例:
const fs = require('fs'); const data = fs.readFileSync('file.txt', 'utf-8'); // 阻塞 console.log(data); console.log('This will run after file read');
-
异步代码:
- 不会阻塞代码执行。异步操作会立即返回,通过回调函数、Promise 或 async/await 在操作完成后处理结果。
- 非阻塞:其他代码可以继续运行。
示例:
const fs = require('fs'); fs.readFile('file.txt', 'utf-8', (err, data) => {if (err) throw err;console.log(data); }); console.log('This will run before file read');
2. Node.js 中的 Buffer 对象是什么? 它有什么作用?
-
Buffer 对象:
Node.js 提供的 Buffer 对象用于操作二进制数据。它是类数组的对象,专为处理数据流中不可变的字节数据设计。 -
作用:
- 处理 I/O 操作(如文件读写、网络通信)中的二进制数据。
- 处理字符编码转换(如 UTF-8 与 Base64)。
-
示例:
const buf = Buffer.from('Hello, World!', 'utf-8'); console.log(buf); // 输出 <Buffer 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21> console.log(buf.toString()); // 输出 "Hello, World!"
3. Node.js 中的 process 对象是什么? 它有哪些常用属性?
-
process
对象:
process
是 Node.js 提供的全局对象,用于与当前运行的 Node.js 进程交互。 -
常用属性和方法:
process.argv
:获取命令行参数。console.log(process.argv); // 输出 ["node", "script.js", "arg1", "arg2"]
process.env
:获取环境变量。console.log(process.env.PATH);
process.cwd()
:返回当前工作目录。console.log(process.cwd());
process.exit([code])
:退出当前进程。process.exit(0); // 退出并返回状态码 0
process.nextTick()
:将回调函数添加到事件循环的下一阶段。
4. Node.js 中的 require 和 import 有什么区别?
特性 | require | import |
---|---|---|
标准 | CommonJS 模块规范 | ES6 模块规范 |
用法 | 动态引入模块 | 静态引入模块 |
运行时支持 | Node.js 原生支持 | 需要 type: "module" 或 esm 支持 |
加载行为 | 模块在第一次调用时加载 | 静态编译时加载 |
示例 | const module = require('x') | import module from 'x' |
5. Node.js 中的回调、Promise 和 async/await 有什么区别?
特性 | 回调 | Promise | async/await |
---|---|---|---|
核心思想 | 通过回调函数处理异步结果 | 链式调用处理异步结果 | 语法糖,基于 Promise |
代码风格 | 嵌套调用(容易回调地狱) | 平展链式结构 | 更接近同步代码结构 |
错误处理 | 需要手动检查并传递错误 | .catch() 捕获错误 | try...catch 捕获错误 |
示例 | fs.readFile(callback) | readFile().then() | const data = await readFile() |
6. Node.js 中的回调函数是什么? 请举例说明
-
回调函数:
一个函数作为参数传递给另一个函数,并在异步操作完成后执行。 -
示例:
const fs = require('fs'); fs.readFile('file.txt', 'utf-8', (err, data) => {if (err) throw err;console.log(data); // 在文件读取完成后执行 });
7. Node.js 中的定时器函数 setImmediate()
和 setTimeout()
有什么区别?
-
setImmediate()
:- 在事件循环的当前阶段完成后立即执行。
- 常用于 I/O 回调完成后的执行。
-
setTimeout()
:- 在指定的时间后执行。
- 常用于延迟任务。
-
优先级:
process.nextTick()
>setImmediate()
>setTimeout()
。 -
示例:
setTimeout(() => console.log('Timeout'), 0); setImmediate(() => console.log('Immediate')); console.log('Sync'); // 输出顺序:Sync -> Immediate -> Timeout
8. Node.js 的 process.nextTick()
有什么作用?
-
作用:
将回调函数添加到当前事件循环的下一次迭代中,比setImmediate()
优先级更高。 -
示例:
process.nextTick(() => console.log('Next Tick')); console.log('Sync'); // 输出顺序:Sync -> Next Tick
-
适用场景:
用于在当前任务完成后立即执行短时间任务。
9. 什么是 Node.js 中的事件发射器(EventEmitter)?它有什么作用?如何使用?
-
EventEmitter
:
Node.js 中的事件机制,用于实现事件的监听和触发。 -
作用:
- 允许模块之间基于事件进行通信。
- 常用于流、服务器等需要异步事件处理的场景。
-
示例:
const EventEmitter = require('events'); const emitter = new EventEmitter();// 注册事件监听器 emitter.on('greet', (name) => console.log(`Hello, ${name}`));// 触发事件 emitter.emit('greet', 'World');
10. 什么是 Node.js 中的事件循环?
-
事件循环:
Node.js 使用的机制,用于处理异步操作。事件循环是一个单线程的执行模型,协调异步 I/O 操作、回调、定时器和事件。 -
工作原理:
- Timers 阶段:执行
setTimeout
和setInterval
的回调。 - Pending Callbacks 阶段:执行 I/O 回调。
- Idle, Prepare 阶段:内部操作。
- Poll 阶段:执行新的 I/O 操作。
- Check 阶段:执行
setImmediate
。 - Close Callbacks 阶段:处理关闭事件的回调。
- Timers 阶段:执行
-
示例:
setTimeout(() => console.log('Timeout'), 0); setImmediate(() => console.log('Immediate')); process.nextTick(() => console.log('Next Tick')); // 输出顺序:Next Tick -> Immediate -> Timeout
Node.js 中的模块加载机制
Node.js的模块加载机制是其核心功能之一,它允许开发者将代码分割成多个模块,以便更好地组织和管理。Node.js的模块分为核心模块和文件模块两类:
-
核心模块:Node.js标准中提供的模块,如fs、http、net等。这些模块被编译成了二进制代码,具有最高的加载优先级。
-
文件模块:存储为单独的文件或文件夹的模块,可能是JS代码、JSON或编译好的C/C++代码。文件模块的加载有两种方式:按路径加载和查找node_modules文件夹。
- 按路径加载:如果require参数以“/”开头,表示以绝对路径查找;如果以“./”或“…/”开头,表示以相对路径查找。
- 查找node_modules文件夹:如果require参数不以“/”、“./”或“…/”开头,且不是核心模块,Node.js会在当前目录下的node_modules文件夹中查找模块,如果未找到,则向上层目录继续查找,直到根目录。
Node.js 全局对象
在Node.js中,全局对象指的是global,所有全局变量(除了global本身以外)都是global对象的属性。在Node.js中,我们不能在最外层定义变量,因为所有用户代码都是属于当前模块的,而模块本身不是最外层上下文。
Node.js 的事件循环机制
Node.js采用事件驱动和异步I/O的方式,实现了一个单线程、高并发的JavaScript运行时环境。其事件循环机制是其异步架构的核心,它不断地检查事件队列,并处理事件队列中的事件,如文件读写、网络请求等。事件循环的实现依赖于以下几个关键组件:
- V8引擎:用于解析JavaScript语法。
- Node API:为上层模块提供系统调用,一般是由C语言来实现,和操作系统进行交互。
- libuv:是跨平台的底层封装,实现了事件循环、文件操作等,是Node.js实现异步的核心。
当主线程空闲时,它会开始循环事件队列,检查是否有要处理的事件。如果是非I/O任务,主线程会亲自处理,并通过回调函数返回到上层调用;如果是I/O任务,则从线程池中拿出一个线程来处理这个事件,并指定回调函数。当线程中的I/O任务完成以后,就执行指定的回调函数,并把这个完成的事件放到事件队列的尾部,等待事件循环。
npm
npm是Node.js官方提供的包管理工具,用于Node.js包的发布、传播、依赖控制。使用npm,可以方便地下载、安装、升级、删除包,也可以发布并维护自己的包。npm提供了命令行工具,允许用户从npm服务器下载别人编写的第三方包到本地使用,或者上传自己编写的包到npm服务器供别人使用。
使用npm管理项目依赖的步骤如下:
- 初始化项目:在项目根目录下运行
npm init
命令,根据提示输入项目信息,生成package.json文件。 - 安装依赖:使用
npm install 包名
命令安装项目所需的第三方包,这些包会被添加到package.json文件的dependencies字段中。 - 更新依赖:使用
npm update 包名
命令更新项目中的第三方包。 - 删除依赖:使用
npm uninstall 包名
命令删除项目中的第三方包。
package.json 文件
package.json是Node.js项目的描述文件,记录了项目的名称、版本、依赖等信息。它的作用包括:
- 定义项目信息:如项目名称、版本、作者、gitHub地址等。
- 定义脚本命令:如npm run build或自定义命令。
- 区分项目依赖和开发依赖:项目依赖在生产和开发阶段都需要,开发依赖仅用于开发阶段。
非阻塞I/O
非阻塞I/O是一种处理I/O操作的方式,它允许程序在等待I/O操作完成时继续执行其他任务,从而提高应用程序的响应性和吞吐量。Node.js采用了非阻塞I/O模型,这是其异步事件驱动架构的核心。Node.js使用libuv库来处理I/O操作,libuv是一个跨平台的异步I/O库,它在内部使用了多种技术来实现非阻塞I/O,包括事件循环、异步I/O操作、回调函数和线程池等。
在 Node.js 中创建一个简单的 HTTP 服务器
在Node.js中创建一个简单的HTTP服务器,可以使用Node.js内置的http模块。以下是一个简单的示例代码:
const http = require('http');const server = http.createServer((req, res) => {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello World\n');
});server.listen(3000, '127.0.0.1', () => {console.log('Server running at http://127.0.0.1:3000/');
});
在 Node.js 中处理 HTTP 请求的路由
在Node.js中处理HTTP请求的路由,可以通过比较请求的路径和URL来实现。以下是一个简单的示例代码,展示了如何处理不同的路由:
const http = require('http');const server = http.createServer((req, res) => {if (req.url === '/') {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Home Page\n');} else if (req.url === '/about') {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('About Page\n');} else {res.writeHead(404, {'Content-Type': 'text/plain'});res.end('Not Found\n');}
});server.listen(3000, '127.0.0.1', () => {console.log('Server running at http://127.0.0.1:3000/');
});
在 Node.js 中解析 JSON 数据
在Node.js中解析JSON数据,可以使用JSON.parse()方法。以下是一个简单的示例代码,展示了如何解析JSON数据:
const fs = require('fs');fs.readFile('data.json', 'utf8', (err, data) => {if (err) throw err;const jsonObj = JSON.parse(data);console.log(jsonObj);
});
在 Node.js 中进行高效的日志处理,避免影响性能
在Node.js中进行高效的日志处理,可以考虑以下几点:
- 使用异步写入:避免阻塞事件循环,影响性能。可以使用fs.appendFile()的异步版本或引入第三方日志库(如winston、bunyan等)。
- 控制日志级别:根据需求设置不同的日志级别(如info、warn、error等),以便在需要时快速定位问题。
- 日志分割:按照时间、大小等因素对日志文件进行分割,避免单个日志文件过大或过于复杂。
- 日志轮转:定期轮转日志文件,避免日志文件无限增长。
- 远程日志:将日志发送到远程服务器或日志管理系统,以便集中管理和分析。
以上内容涵盖了Node.js的模块加载机制、全局对象、事件循环机制、npm的使用、package.json文件的作用、非阻塞I/O的实现、HTTP服务器的创建、HTTP请求路由的处理、JSON数据的解析以及高效的日志处理等方面。希望这些信息能帮助你更好地理解和使用Node.js。
相关文章:

前端热门面试题目——React、Node
img 标签的 srcset 属性的作用 srcset 属性允许开发者为不同设备或分辨率提供多个图像选项,优化加载的图片以适应设备的屏幕大小和分辨率。这提高了性能和用户体验。 示例: <img src"default.jpg" srcset"small.jpg 480w, medium.j…...

Ansible自动化一键部署单节点集群架构
自动化部署利器:Ansible 一键部署脚本 在现代IT基础设施管理中,Ansible以其简洁、强大的自动化能力脱颖而出。以下是精心打造的Ansible自动化一键部署脚本,旨在简化部署流程,提升效率,确保一致性和可靠性。 通过这个…...

电脑插入耳机和音响,只显示一个播放设备
1. 控制面板-硬件和声音-Realtek高清音频-扬声器-设备高级设置-播放设备里选择使用前部和后部输出设备同时播放两种不同的音频流 在声音设置中就可以看到耳机播放选项...

家政小程序开发,打造便捷家政生活小程序
目前,随着社会人就老龄化和生活压力的加重,家政服务市场的需求正在不断上升,家政市场的规模也正在逐渐扩大,发展前景可观。 在市场快速发展的影响下,越来越多的企业开始进入到市场中,同时家政市场布局也发…...

tcpdump抓包wireshark分析
背景 分析特定协议的数据包,如 HTTP、DNS、TCP、UDP 等,诊断网络问题,例如连接故障、延迟和数据包丢失。 大概过程 1.安装tcpdump yum update yum install tcpdump2.抓包,从当前时间起,一小时后停止,…...

文件无法直接拖入zotero
解决方法:取消管理员权限打开zotero。 具体如下:右键zotero应用程序,打开属性,选择“兼容性”,点击底下的“更改所有用户的设置”,在弹出的框中取消“以管理员身份运行此程序”。如下所示:...

使用 useMemo 和 React.memo 优化 React 组件渲染
在 React 中,性能优化是一个重要的主题,特别是在复杂的组件树中。本文将演示如何在同一个父组件中使用 useMemo 和 React.memo 来优化子组件的渲染。 1. 组件结构 创建一个父组件,包含两个子组件: MemoChild:使用 R…...

ISAAC SIM踩坑记录--添加第三方3D场景
ISAAC SIM仿真首先就是要有合适的3D场景,官方提供了一些场景,如果不能满足要求,那就只能自己建。 对于我这种不会3D建模的菜鸟,只能到网上下载了,sketchfab就是一个不错的平台,有不少免费资源可以下载。 …...

Git 详解
Git 详解 Git 是一个分布式版本控制系统,用于高效地管理项目代码的版本历史。它是目前最流行的版本控制工具之一,广泛应用于软件开发领域。Git 的分布式架构允许开发者在本地进行代码的版本管理,并与远程仓库同步,实现团队协作。…...

Linux操作系统3-文件与IO操作1(从C语言IO操作到系统调用)
上篇文章:Linux操作系统2-进程控制3(进程替换,exec相关函数和系统调用)_execv系统调用-CSDN博客 本篇代码Gitee仓库:myLerningCode 橘子真甜/linux学习 - 码云 - 开源中国 (gitee.com) 本篇重点:C语言基础IO与系统调用 目录 一.…...

【Python网络爬虫笔记】8- (BeautifulSoup)抓取电影天堂2024年最新电影,并保存所有电影名称和链接
目录 一. BeautifulSoup的作用二. 核心方法介绍2.1 构造函数2.2 find()方法2.3 find_all()方法2.4 select()方法 三. 网络爬虫中使用BeautifulSoup四、案例爬取结果 一. BeautifulSoup的作用 解析HTML/XML文档:它可以将复杂的HTML或XML文本转换为易于操作的树形结构…...

Rancher V2.7.0安装教程
1、执行Docker命令 docker run -d --privileged --restartunless-stopped -p 80:80 -p 443:443 -v /home/rancher:/var/lib/rancher --name rancher registry.cn-hangzhou.aliyuncs.com/rancher/rancher:v2.7.0 注:如果容器启动失败,参考我另外一篇文章…...

STM32MX 配置CANFD收发通讯
一、环境 MCU:STM32G0B1CEU6 CAN收发器:JIA1042 二、MX配置 配置SYS 配置canfd并开启中断,我开了两个FDCAN,配置是一样的,这里贴一下波特率的计算公式: 也就是:CAN时钟频率/预分频器/&…...

(12)时间序列预测之MICN(CNN)
文章目录 前言1. challenge 一、网络结构1. MHDecomp2. Trend-cyclical Prediction Block3. Seasonal Prediction BlockMIC LayerMerge 实验结果1.长时预测 总结参考 文章信息 模型: MICN (Multi-scale Isometric Convolution Network)关键词: 长时预测…...

嵌入式蓝桥杯学习3 外部中断实现按键
Cubemx配置 前面的配置依旧一样。 原文链接:https://blog.csdn.net/m0_74246768/article/details/144227188 1.打开cubemx,将PB0到PB1配置为GPIO_EXTI模式。 2.在System-Core中点击GPIO,选择PB0到PB2, GPIO_Mode(触…...

自由学习记录(29)
FileStream FileStream 是 .NET 中用于文件操作的重要类,位于 System.IO 命名空间中。它提供了对文件的同步和异步读写操作。以下是它的方法签名和重载的详细介绍: 构造函数签名和重载 FileStream 提供多个构造函数,允许在创建实例时指定文…...

使用YOLO系列txt目标检测标签的滑窗切割:批量处理图像和标签的实用工具
使用YOLO系列txt目标检测标签的滑窗切割:批量处理图像和标签的实用工具 使用YOLO的TXT目标检测标签的滑窗切割:批量处理图像和标签的实用工具背景1. 代码概述2. 滑窗切割算法原理滑窗切割步骤:示例: 3. **代码实现**1. **加载标签…...

架构10-可观测性
零、文章目录 架构10-可观测性 1、可观测性 (1)可观测性的背景 **历史沿革:**可观测性最初由匈牙利数学家鲁道夫卡尔曼提出,用于线性动态控制系统。后来,该概念被引入到计算机科学中。**现代意义:**在分…...

git管理Unity项目的正确方式
git管理Unity项目的正确打开方式 前言:对于刚开始git进行unity项目管理的时候,我采取的方式是全部文件上传,文件数量太多以及上传太大,我尝试过一下几个方法: 利用git的LFS大文件进行传方式,可行但比较麻…...

openssl使用哈希算法生成随机密钥
文章目录 一、openssl中随机数函数**OpenSSL 随机数函数概览**1. **核心随机数函数** **常用函数详解**1. RAND_bytes2. RAND_priv_bytes3. RAND_seed 和 RAND_add4. RAND_status **随机数生成器的熵池****常见用例****注意事项** 二、使用哈希算法生成随机的密钥 一、openssl中…...

将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式
文章目录 将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式MathType安装问题MathType30天试用延期MathPage.wll文件找不到问题 将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式 word自带公式编辑器编辑的公式格式: MathType编辑的格式&a…...

校园失物招领系统基于 SpringBoot:点亮校园归还遗失物之光
2系统开发环境 2.1vue技术 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 [5] 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第…...

dhcpd服务器的配置与管理(超详细!!!)
前提条件: (1)虚拟机能够联网(如果nat模式不能联网的看另一期) CentOS7 NAT模式不能联网-CSDN博客 (2)系统是Centos8,因为下载的dhcp-server软件包版本和Centos7不匹配,如果你能成…...

Qml之基本控件
一.Qml常用控件 1.Text(显示普通文本和富文本) 1.1显示普通文本: Window { visible: true width: 320 height: 240 title: qsTr("Hello World") Text { text: "Hello World!" font.family: "Helvetica" font.pointSize: 24 color:…...

【Java从入门到放弃 之 Stream API】
Java Stream API Stream API行为参数化传递代码Lambda表达式Lambda 表达式的语法方法引用 Lambda 表达式的实际应用集合操作并发编程 Lambda 表达式的注意事项总结 Stream API Java8提供了一个全新的API - Stream。引入这个Stream的主要目的,一个是可以支持更好的并…...

Ruby On Rails 笔记1——Rails 入门
突然想跟着官方文档把Ruby On Rails过一遍,把一些有用的记下来就可以一直看了,do它! https://guides.rubyonrails.org/v7.2/ 注:官网是英文文档,我自己翻译了一下,不确保完全准确,只供自己学习开发使用。 …...

高效开发 Python Web 应用:FastAPI 数据验证与响应体设计
高效开发 Python Web 应用:FastAPI 数据验证与响应体设计 目录 🧑💻 FastAPI 的数据验证系统与 Pydantic 模型📦 响应体与模型:定义响应数据的最佳实践🔄 响应模型与查询参数的结合:增强灵活…...

基于“开源 2+1 链动 O2O 商城小程序”的门店拉新策略与流程设计
摘要:在数字化商业浪潮席卷之下,实体门店面临着激烈的市场竞争,如何高效拉新成为关乎门店生存与发展的关键问题。本文聚焦于“开源 21 链动 O2O 商城小程序”,深入探讨结合多种手段的门店拉新策略及详细流程设计。通过剖析到店扫码…...

33.5 remote实战项目之设计prometheus数据源的结构
本节重点介绍 : 项目要求 通过remote read读取prometheus中的数据通过remote write向prometheus中写入数据 准备工作 新建项目 prome_remote_read_write设计prometheus 数据源的结构初始化 项目要求 通过remote read读取prometheus中的数据通过remote write向prometheus中写…...

微服务springboot详细解析(一)
目录 1.Spring概述 2.什么是SpringBoot? 3.第一个SpringBoot程序 4.配置参数优先级 5.springboot自动装配原理 6.SpringBootApplication&SpringApplication.run 7.ConfigurationProperties(prefix "") 8.Validated数据校验 29、聊聊该如何写一…...