JavaScript 前端开发 是什么?

devtools/2024/12/28 14:56:00/

一、引言

JavaScript 作为前端开发领域的核心语言,在构建现代 Web 应用程序中发挥着至关重要的作用。从创建交互性网页元素到构建复杂的单页应用(SPA)和 Progressive Web App(PWA),JavaScript 的应用无处不在。它与 HTML 和 CSS 紧密结合,赋予网页动态行为和丰富的用户体验,无论是简单的表单验证、实时数据更新,还是复杂的动画效果和全功能的应用逻辑,JavaScript 都是前端开发者实现创意和满足用户需求的得力工具。

二、JavaScript 基础语法

(一)变量与数据类型

JavaScript 是一种弱类型语言,变量可以通过 varlet 和 const 关键字声明。var 具有函数级作用域,而 let 和 const 具有块级作用域,const 用于声明常量,其值一旦赋值就不能被重新赋值。基本数据类型包括 Number(数字)、String(字符串)、Boolean(布尔值)、Null(空值)、Undefined(未定义值),以及复杂数据类型 Object(对象)和 Array(数组)等。例如:

javascript>javascript">let num = 10; // 数字类型
const str = "Hello, JavaScript"; // 字符串类型
let bool = true; // 布尔类型
let obj = { name: "John", age: 30 }; // 对象类型
let arr = [1, 2, 3, 4]; // 数组类型

(二)运算符

JavaScript 支持常见的算术运算符(+-*/%)、赋值运算符(=+=-= 等)、比较运算符(=====>< 等)、逻辑运算符(&&||!)等。特别要注意 == 和 === 的区别,== 会进行类型转换后比较值,而 === 严格比较值和类型,推荐在大多数情况下使用 === 以避免潜在的类型转换问题。

(三)控制结构

包括 if-else 条件语句、switch 语句、for 循环、while 循环和 do-while 循环等。例如:

javascript>javascript">// if-else 示例
let age = 25;
if (age >= 18) {console.log("成年人");
} else {console.log("未成年人");
}// for 循环示例
for (let i = 0; i < 5; i++) {console.log(i);
}

for...of 循环用于遍历可迭代对象(如数组、字符串等),for...in 循环用于遍历对象的属性,但需要注意其遍历顺序可能不符合预期,且会遍历到原型链上的属性,使用时应谨慎或结合 hasOwnProperty 方法进行过滤。

三、函数与作用域

(一)函数定义与调用

函数可以通过函数声明和函数表达式两种方式定义。函数声明会被提升到作用域顶部,而函数表达式不会。例如:

javascript>javascript">// 函数声明
function add(a, b) {return a + b;
}// 函数表达式
const subtract = function(a, b) {return a - b;
};console.log(add(5, 3));
console.log(subtract(5, 3));

函数还可以作为参数传递给其他函数(回调函数),以及返回函数(闭包),闭包在 JavaScript 中常用于创建私有变量和保存函数执行的上下文。

(二)作用域链

JavaScript 具有词法作用域,函数在定义时就确定了其作用域。作用域链是由当前执行环境的变量对象、父级执行环境的变量对象等逐级向上组成的一个链式结构。当在函数内部访问一个变量时,JavaScript 引擎会首先在当前函数的作用域内查找,如果找不到,则沿着作用域链向上查找,直到全局作用域。理解作用域链对于正确使用变量和避免变量名冲突至关重要,同时也是理解闭包等高级概念的基础。

四、对象与面向对象编程(OOP)

(一)对象创建与属性访问

对象可以通过字面量、构造函数和 Object.create 方法创建。例如:

javascript>javascript">// 字面量方式
let person = {firstName: "John",lastName: "Doe",age: 30,fullName: function() {return this.firstName + " " + this.lastName;}
};// 构造函数方式
function Person(firstName, lastName, age) {this.firstName = firstName;this.lastName = lastName;this.age = age;this.fullName = function() {return this.firstName + " " + this.lastName;};
}
let anotherPerson = new Person("Jane", "Smith", 25);console.log(person.fullName());
console.log(anotherPerson.fullName());

对象的属性可以通过点号(.)或方括号([])访问,方括号访问方式在属性名是动态获取时非常有用。

(二)原型与原型链

每个 JavaScript 对象都有一个原型对象(__proto__),原型对象又可以有自己的原型,形成原型链。当访问对象的属性或方法时,如果对象本身不存在该属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到或到达 Object.prototype 的原型链顶端。通过原型可以实现属性和方法的共享,减少内存占用,同时也是 JavaScript 实现继承的基础机制。例如:

javascript>javascript">function Animal(name) {this.name = name;
}
Animal.prototype.sayHello = function() {console.log("Hello, I'm " + this.name);
};function Dog(name, breed) {Animal.call(this, name);this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;let myDog = new Dog("Buddy", "Golden Retriever");
myDog.sayHello();

在上述代码中,Dog 构造函数通过原型链继承了 Animal 的属性和方法,同时又拥有自己独特的属性 breed

五、DOM 操作

(一)获取 DOM 元素

可以通过 document.getElementByIddocument.getElementsByTagNamedocument.getElementsByClassName 以及 document.querySelector 和 document.querySelectorAll 等方法获取 HTML 文档中的元素。例如:

javascript>javascript">// 通过 id 获取元素
let myElement = document.getElementById("myId");// 通过标签名获取元素列表
let allParagraphs = document.getElementsByTagName("p");// 通过类名获取元素列表
let elementsWithClass = document.getElementsByClassName("myClass");// 通过 CSS 选择器获取单个元素
let specificElement = document.querySelector("#myId.myClass");// 通过 CSS 选择器获取元素列表
let multipleElements = document.querySelectorAll("p.myClass");

(二)修改 DOM 元素

获取到 DOM 元素后,可以修改其属性、内容和样式。例如:

javascript>javascript">let element = document.getElementById("myElement");
// 修改属性
element.setAttribute("src", "new-image.jpg");
// 修改内容
element.textContent = "新的文本内容";
// 修改样式
element.style.color = "red";
element.style.fontSize = "20px";

还可以通过 classList 属性添加、移除和切换元素的类名,实现更灵活的样式控制。

(三)事件处理

可以使用 addEventListener 方法为 DOM 元素添加各种事件监听器,如 clickmouseoverkeydown 等,当事件发生时执行相应的回调函数。例如:

javascript>javascript">let button = document.getElementById("myButton");
button.addEventListener("click", function() {console.log("按钮被点击了");
});

事件冒泡和捕获机制决定了事件在 DOM 树中的传播顺序,合理利用事件委托可以提高事件处理的效率,尤其是在处理大量具有相同行为的元素时,将事件监听器添加到父元素上,通过判断事件源来执行相应逻辑。

六、异步编程

(一)回调函数

回调函数是异步编程的基础模式之一,函数作为参数传递给另一个函数,在特定事件发生或异步操作完成时被调用。例如,在进行 AJAX 请求时:

javascript>javascript">function handleResponse(response) {console.log("请求成功,响应数据:", response);
}function makeAjaxRequest(url, callback) {let xhr = new XMLHttpRequest();xhr.open("GET", url, true);xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {callback(JSON.parse(xhr.responseText));}};xhr.send();
}makeAjaxRequest("https://example.com/api/data", handleResponse);

然而,回调函数存在回调地狱问题,当多个异步操作相互依赖时,代码会嵌套多层,难以阅读和维护。

(二)Promise

Promise 是一种更优雅的异步处理方式,它代表一个异步操作的最终完成或失败,并返回一个结果值。一个 Promise 处于三种状态之一:pending(进行中)、fulfilled(已成功)、rejected(已失败)。例如:

javascript>javascript">function fetchData() {return new Promise((resolve, reject) => {makeAjaxRequest("https://example.com/api/data", (response) => {if (response) {resolve(response);} else {reject("请求失败");}});});
}fetchData().then((data) => {console.log("数据获取成功:", data);return processData(data);}).then((processedData) => {console.log("数据处理成功:", processedData);}).catch((error) => {console.error("发生错误:", error);});

Promise 可以通过 then 方法链式调用,处理异步操作的成功结果,通过 catch 方法捕获错误,使得异步代码的结构更加清晰,易于理解和维护。

(三)async/await

async/await 是基于 Promise 的一种更简洁的异步编程语法糖,使得异步代码看起来像同步代码,提高了代码的可读性。async 函数总是返回一个 Promise,await 只能在 async 函数内部使用,用于暂停 async 函数的执行,等待 Promise 被解决(fulfilled)或被拒绝(rejected)。例如:

javascript>javascript">async function getData() {try {let response = await fetchData();let processedData = await processData(response);console.log("最终结果:", processedData);} catch (error) {console.error("错误:", error);}
}getData();

使用 async/await 可以更清晰地表达异步操作的顺序和逻辑,避免了 Promise 链式调用的多层嵌套,同时也方便进行错误处理。

七、JavaScript 框架与库

(一)React

React 是一个用于构建用户界面的 JavaScript 库,采用组件化开发思想,通过虚拟 DOM 提高渲染效率。React 组件可以是函数组件或类组件,函数组件使用 React Hooks 来处理状态和副作用。例如:

javascript>javascript">import React from 'react';
import ReactDOM from 'react-dom';function App() {const [count, setCount] = React.useState(0);return (<div><p>计数:{count}</p><button onClick={() => setCount(count + 1)}>增加</button></div>);
}ReactDOM.render(<App />, document.getElementById('root'));

React 生态系统还包括 React Router 用于路由管理,Redux 或 MobX 用于状态管理等,它们一起为构建大型复杂的单页应用提供了强大的支持。

(二)Vue

Vue 是一个渐进式 JavaScript 框架,易于上手,提供了简洁的模板语法和响应式数据绑定。例如:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head><body><div id="app"><p>{{ message }}</p><button v-on:click="changeMessage">改变消息</button></div><script>new Vue({el: '#app',data: {message: 'Hello Vue!'},methods: {changeMessage() {this.message = '新的消息';}}});</script>
</body></html>

Vue 也有自己的生态系统,如 Vue Router 用于路由,Vuex 用于状态管理,以及一系列的 UI 组件库,方便开发者快速构建应用。

(三)Angular

Angular 是一个功能全面的前端框架,采用 TypeScript 开发,具有强大的依赖注入、模板系统和模块管理功能。例如:

javascript>javascript">import { Component } from '@angular/core';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})
export class AppComponent {title = 'angular-app';count = 0;increment() {this.count++;}
}

在上述 Angular 组件中,通过 @Component 装饰器定义组件的元数据,包括选择器、模板和样式等,组件类中定义了数据和方法,与模板进行双向数据绑定和交互。

八、性能优化

(一)代码优化

  • 减少不必要的计算和操作,避免在循环中进行复杂的函数调用或创建新的对象。例如,将循环不变量提到循环体外,缓存函数调用结果等。
  • 优化算法复杂度,选择更高效的算法来解决问题,如使用哈希表替代数组查找,二分查找替代线性查找等。
  • 避免全局变量的过度使用,过多的全局变量会增加命名冲突风险,并且在浏览器环境中会占用更多的内存,尽量使用局部变量和模块来封装代码逻辑。

(二)DOM 操作优化

  • 减少不必要的 DOM 操作,批量修改元素的样式和属性,而不是逐个修改,例如使用 classList 一次性切换多个类名,或者使用 documentFragment 来构建复杂的 DOM 结构,然后一次性插入到页面中,减少页面重排(reflow)和重绘(repaint)的次数。
  • 优化事件绑定,使用事件委托将多个子元素的相同事件绑定到父元素上,通过判断事件源来执行相应逻辑,减少事件监听器的数量,提高性能。

(三)资源加载优化

  • 合理使用懒加载,对于图片、脚本和样式等资源,在需要时才进行加载,例如对于页面中初始不可见的部分或需要用户交互后才显示的内容,使用 Intersection Observer API 等技术来实现资源的懒加载,提高页面的初始加载速度。
  • 压缩和合并资源,通过工具将 JavaScript 和 CSS 文件进行压缩,去除不必要的空格和注释,同时合并多个小文件为一个大文件,减少浏览器的请求次数,提高资源加载效率。

九、测试与调试

(一)单元测试

使用测试框架如 JestMocha 等编写单元测试用例,对 JavaScript 函数和模块进行独立的功能测试。例如,使用 Jest 测试一个简单的加法函数:

javascript>javascript">function add(a, b) {return a + b;
}test('add 函数应该正确相加两个数', () => {expect(add(2, 3)).toBe(5);
});

单元测试有助于确保代码的正确性,方便在代码修改后快速进行回归测试,发现潜在的问题,提高代码质量和可维护性。

(二)集成测试

集成测试用于测试多个模块或组件之间的交互是否正常,模拟真实的使用场景,检查数据在不同组件之间的传递和处理是否符合预期。例如,在一个使用 React 和 Redux 的应用中,测试一个包含多个组件和 Redux 状态管理的功能模块,通过模拟用户操作和检查 Redux 状态的变化以及组件的渲染结果来验证集成的正确性。

(三)调试技巧

  • 使用浏览器开发者工具,如 Chrome DevTools,可以在 Sources 面板中设置断点,单步执行代码,查看变量的值和调用栈,分析代码的执行流程,找出错误和性能瓶颈。
  • 使用 console.log 等调试语句输出关键变量的值,但要注意在生产环境中及时删除或禁用这些调试语句,以免影响性能和泄露敏感信息。
  • 对于异步代码的调试,可以使用 async/await 结合 try-catch 块,或者在 Promise 的 then 和 catch 方法中添加调试语句,以便更好地理解异步操作的执行顺序和错误处理情况。

十、安全考量

(一)跨站脚本攻击(XSS)防范

  • 对用户输入进行严格的过滤和转义,避免将未经过滤的用户输入直接插入到 HTML 页面中。例如,使用 DOMPurify 等库对用户输入进行净化,防止恶意脚本被执行。当用户在评论区输入内容时,应确保其中的 <script> 标签及其他潜在的危险脚本代码被正确转义或移除,防止攻击者通过注入恶意脚本来窃取用户信息、篡改页面内容或发起钓鱼攻击等。
  • 设置合适的 Content-Security-Policy(CSP)头部,限制页面可以加载的资源来源,如脚本、样式表、图片等。通过明确指定允许的源,阻止外部恶意脚本的加载和执行,降低 XSS 攻击的风险。例如,只允许从本域加载脚本,阻止来自其他未知域的脚本注入。

(二)跨站请求伪造(CSRF)防范

  • 在服务器端为用户生成随机的 CSRF 令牌,并在每次敏感操作的表单或请求中包含该令牌。当服务器收到请求时,验证令牌的有效性,确保请求来自用户的真实操作而非伪造的请求。例如,在用户登录后,为其生成一个唯一的 CSRF 令牌,存储在用户的会话中,并在用户提交表单(如修改密码、转账等操作)时,将令牌作为隐藏字段包含在表单中,服务器端验证令牌是否与用户会话中的一致,不一致则拒绝请求。
  • 检查请求的 Referer 头部(虽然不是完全可靠,但可作为一种辅助手段),确保请求来自合法的页面源。如果请求的 Referer 与预期的源不匹配,可能是 CSRF 攻击的迹象,服务器可以拒绝该请求,进一步增强安全性。

(三)数据验证与 sanitization

  • 在客户端和服务器端都要对输入数据进行全面的验证,包括数据类型、长度、格式等。例如,对于用户注册表单中的电子邮件地址,应验证其是否符合电子邮件的格式规范;对于密码,应确保其强度满足一定要求,如包含字母、数字和特殊字符,且长度在合理范围内。在服务器端,对所有传入的数据进行再次验证,防止客户端验证被绕过的情况发生。
  • 对输出数据进行 sanitization,防止敏感信息泄露。在向页面输出用户数据或数据库查询结果时,确保敏感数据(如用户密码、信用卡信息等)被适当处理,例如进行加密存储和显示时脱敏处理,避免将完整的敏感信息暴露给用户或潜在的攻击者。

十一、JavaScript 与后端交互

(一)AJAX 与 Fetch API

  • XMLHttpRequest(XHR)是传统的用于在网页中进行异步数据传输的对象,通过它可以向服务器发送 HTTP 请求并接收响应,实现无刷新页面更新数据。例如:

javascript>javascript">let xhr = new XMLHttpRequest();
xhr.open("GET", "https://example.com/api/data", true);
xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {let response = JSON.parse(xhr.responseText);console.log(response);}
};
xhr.send();

  • Fetch API 提供了一种更简洁、现代化的方式来进行网络请求,基于 Promise 实现,使得异步操作的处理更加清晰和方便。例如:

javascript>javascript">fetch("https://example.com/api/data").then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));

无论是 XHR 还是 Fetch API,都可以设置请求头、发送不同类型的请求(如 POST、PUT、DELETE 等),并处理服务器返回的各种状态码和数据格式,实现前端与后端的数据交互,为构建动态 Web 应用提供基础支持。

(二)RESTful API 交互

遵循 REST 架构风格,前端与后端通过统一的接口进行资源的交互。例如,对于一个博客应用,前端可能会向 /api/posts 发送 GET 请求获取文章列表,向 /api/posts/{id} 发送 GET 请求获取特定文章的详细信息,向 /api/posts 发送 POST 请求创建新文章等。在与 RESTful API 交互时,前端需要正确处理不同的 HTTP 方法和对应的操作,将用户的操作转换为合适的 API 请求,并根据服务器的响应更新页面状态和数据显示。同时,要注意处理网络错误、请求超时等情况,提供良好的用户体验,确保前端应用与后端 API 的高效、稳定通信。

(三)WebSocket 通信

WebSocket 提供了一种全双工的通信通道,允许前端和后端实时双向通信,适用于需要即时推送数据的场景,如实时聊天、股票行情更新、在线游戏等。在前端,通过创建 WebSocket 实例连接到服务器的 WebSocket 端点,例如:

javascript>javascript">let socket = new WebSocket("wss://example.com/socket");
socket.onopen = function() {console.log("WebSocket 连接已建立");socket.send("Hello, Server!");
};
socket.onmessage = function(event) {console.log("收到服务器消息:", event.data);
};
socket.onclose = function() {console.log("WebSocket 连接已关闭");
};

后端同样需要实现 WebSocket 服务器端逻辑,处理前端的连接请求、接收和发送消息,实现实时数据的推送和交互,增强 Web 应用的实时性和交互性,突破传统 HTTP 请求 - 响应模式的限制,为用户提供更加流畅和即时的体验。

十二、新兴趋势与未来展望

(一)JavaScript 新特性与 ECMAScript 标准发展

随着 ECMAScript 标准的不断演进,JavaScript 语言本身也在持续发展,引入了许多新的特性。例如,Optional Chaining(可选链操作符 ?.)允许更安全地访问嵌套对象的属性,避免因属性不存在而导致的 TypeErrorNullish Coalescing Operator(空值合并运算符 ??)提供了一种简洁的方式来处理 null 和 undefined 值,为变量设置默认值。此外,BigInt 数据类型用于处理超出 Number 类型范围的大整数,Promise.allSettled 方法可以同时处理多个 Promise 的最终状态,无论它们是成功还是失败,这些新特性都在不断提升 JavaScript 的表达能力和开发效率,开发者需要及时跟进学习,以便在项目中合理应用,编写更简洁、健壮的代码。

(二)前端框架的演进与融合

前端框架不断演进,在性能优化、开发体验和功能扩展方面持续改进。例如,React 正在探索更多的并发模式和优化策略,如 React Server Components,旨在进一步提高应用的性能和可扩展性,减少首次内容绘制时间,提升用户体验。同时,不同框架之间也在相互借鉴和融合,一些框架开始整合其他框架的优秀特性,如 Vue 3 在响应式系统等方面的改进借鉴了 React 的一些理念,而 React 也在不断优化其模板语法和开发工具链,向更简洁、高效的方向发展。这种演进和融合趋势将促使前端开发更加高效、灵活,开发者能够根据项目需求选择最合适的技术方案,而不再局限于单一框架的使用。

(三)JavaScript 在跨平台开发中的应用拓展

JavaScript 的应用范围已经不仅限于 Web 浏览器,借助于技术如 React NativeElectron 等,它在移动应用开发和桌面应用开发领域也发挥着重要作用。React Native 允许使用 JavaScript 和 React 开发原生移动应用,能够复用大量的前端代码和开发经验,同时提供接近原生应用的性能和用户体验,通过与原生模块的交互,访问设备的各种功能,如摄像头、GPS 等,为跨平台移动应用开发提供了高效的解决方案。Electron 则使得使用 JavaScript、HTML 和 CSS 构建跨平台桌面应用成为可能,许多知名的桌面应用如 Visual Studio Code、Slack 等都是基于 Electron 开发的,这进一步拓宽了 JavaScript 的应用边界,未来 JavaScript 在跨平台开发领域有望继续发展,与原生开发更加紧密地结合,实现更强大、更便捷的应用开发体验。

(四)人工智能与机器学习在 JavaScript 中的应用

随着人工智能和机器学习技术的普及,JavaScript 也开始涉足这一领域,出现了一些用于在浏览器中进行机器学习的库和框架,如 TensorFlow.js。它允许开发者在浏览器环境中训练和运行机器学习模型,无需依赖服务器端的计算资源,实现实时的、基于机器学习的交互功能,例如图像识别、语音识别、自然语言处理等。这为前端开发带来了全新的可能性,如在网页中实现实时的图像分类、智能聊天机器人等功能,提升用户体验和应用的智能化水平。随着硬件性能的提升和相关技术的不断成熟,JavaScript 在人工智能和机器学习领域的应用将更加广泛和深入,为前端开发注入新的活力和创新点,推动 Web 应用向更加智能、个性化的方向发展。

JavaScript 前端开发领域在不断发展和创新,从语言基础到框架应用,从性能优化到安全防护,再到与后端的交互以及新兴技术的融合,每一个方面都在持续演进。开发者需要保持学习的热情和敏锐的技术洞察力,不断提升自己的技能水平,以适应这个快速变化的领域,开发出更加高效、安全、智能的 Web 应用程序,满足用户日益增长的需求和期望,推动前端技术的不断进步和发展。


http://www.ppmy.cn/devtools/146140.html

相关文章

AIGC与娱乐产业:颠覆创意与生产的新力量

个人主页&#xff1a;云边有个稻草人-CSDN博客 目录 引言 第一部分&#xff1a;AIGC技术概述 1.1 AIGC的基本原理 1.2 AIGC在娱乐产业中的应用 第二部分&#xff1a;AIGC在娱乐产业的实际应用案例 2.1 自动生成音乐&#xff1a;AIGC如何创作旋律 示例代码&#xff1a;使…

【自信息、信息熵、联合熵、条件熵、互信息】

文章目录 一、自信息 I(X)二、信息熵&#xff1a;衡量系统的混乱程度信息熵 H(X)联合熵 H(X,Y) 三、条件熵H(Y|X) 联合熵H(X,Y) - 信息熵H(X)四、互信息 I(X,Y)五、总结References 一、自信息 I(X) 自信息(Self-information) 是由香农提出的&#xff0c;用来衡量单一事件发生…

PDF书籍《手写调用链监控APM系统-Java版》第5章 插桩插件与bytebuddy字节码增强

本人阅读了 Skywalking 的大部分核心代码&#xff0c;也了解了相关的文献&#xff0c;对此深有感悟&#xff0c;特此借助巨人的思想自己手动用JAVA语言实现了一个 “调用链监控APM” 系统。本书采用边讲解实现原理边编写代码的方式&#xff0c;看本书时一定要跟着敲代码。 作者…

如何实现底部导航栏

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了TextField Widget,本章回中将介绍BottomNavigationBar Widget。闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中将介绍一个新的Widget:BottomNavigationBar,它就是我们经常在App中看到了底部…

【ES6复习笔记】模板字符串(3)

介绍 模板字符串是 ES6 引入的一种新的字符串声明方式&#xff0c;它使用反引号&#xff08;&#xff09;来定义字符串&#xff0c;而不是单引号&#xff08;&#xff09;或双引号&#xff08;"&#xff09;。模板字符串可以包含变量、表达式和换行符&#xff0c;这使得它…

mongodb和Cassandra

mongodb的一致性问题&#xff1a; 15.MongoDB的一致性(读关注与写关注)_mongo w选项-CSDN博客 孤儿节点问题&#xff1a; 技术干货 | MongoDB 偶遇孤儿文档及处理方法-腾讯云开发者社区-腾讯云 分片集群MongoDB迁移前清除孤儿文档 由数据迁移至MongoDB导致的数据不一致问题…

ctfshow-web 151-170-文件上传

我们首先想到就是上传一句话木马。但是看源代码限制了png。 &#xff08;1&#xff09;改前端代码。 这里是前端限制了上传文件类型&#xff0c;那我们就改一下就好了嘛,改成php。 这里直接修改不行&#xff0c;给大家推荐一篇简短文章&#xff0c;大家就会了&#xff08;一开始…

前端经典面试合集(二)——Vue/React/Node/工程化工具/计算机网络

1. 说说 Vue 中的 Diff 算法 Vue 的 Diff 算法 主要用于优化虚拟 DOM 和实际 DOM 之间的比较过程。它通过以下几种策略来提高性能&#xff1a; 最小化对 DOM 的操作&#xff1a;Vue 通过在内存中构建一个虚拟 DOM 树&#xff0c;在虚拟 DOM 树与真实 DOM 树之间进行比较和更新…