循环渲染中为何不建议index做key?
在现代前端开发中,无论是 React、Vue 还是其他基于虚拟 DOM 的框架,循环渲染列表时都会用到一个叫做 key 的属性。合理地使用 key 能极大地提高页面的更新效率和组件状态管理,而不恰当地使用则可能导致性能问题和状态混乱。本文将详细介绍 key 的作用,并解释为何推荐不要使用数组索引(index)作为 key。 key 的作用1. 唯一标识每个列表项当你通过循环渲染一个列表时,每个列表项都需要一个独一无二的标识符,这就是 key 的作用。通过 key,框架能够准确地识别出每个元素,确定它们在数据更新时的变化。 例如,在 React 中,key 用于帮助虚拟 DOM 快速判断哪些元素发生了改变、哪些需要重新渲染或移除,从而提高页面更新的性能。 2. 保持组件状态使用正确的 key,可以确保在列表项发生增删或重新排序时,各个组件的内部状态能够正确地保留和复用。例如,如果你有一个表单组件列表,使用唯一的 key 能保证当用户在一个输入框中输入内容后,列表重新排序时,输入框中的数据不会错误地传递到其他组件上。 为什么不推荐使用 index 作为 key?1....
同一链接如何PC、手机展示两套应用
在实际项目中,为了兼容多终端体验,我们常常希望通过同一个链接来为不同设备提供不同版本的页面。例如,在 PC 端展示完整的 Web 应用,而在手机端展示轻量化、优化的 H5 应用。如何实现这一目标? 本文将介绍两种主要方案: 服务端用户代理检测重定向 客户端响应式加载或动态模块切换 服务端检测用户代理原理通过服务器检测 HTTP 请求头中的 User-Agent,根据设备类型选择性地返回不同版本的页面。这样,同一个 URL 在 PC 和手机访问时,会由服务器根据检测结果决定返回哪个 HTML 模板。 示例(Node.js + Express)下面是一个简单的示例,通过 Express 中间件检测 User-Agent 并重定向到不同页面。 123456789101112131415161718const express = require('express');const app = express();// 模拟 PC 与 H5 页面(假设它们分别位于 /web 和 /h5)app.get('/', (req, res)...
如何减少项目中的if-else结构
在实际项目开发中,我们经常会遇到大量 if-else 判断逻辑。虽然简单的分支结构对初学者来说比较直观,但当项目规模扩大、业务逻辑复杂时,冗长的 if-else 结构会导致代码难以维护、扩展和测试。 本文将详细介绍几种有效减少 if-else 结构的方法,并给出 JavaScript 代码示例,帮助你写出更清晰、更具扩展性的代码。 为什么要减少 if-else? 降低代码复杂度:过多的 if-else 分支会使代码阅读困难,增加理解成本。 提高可维护性:业务逻辑变化时,嵌套过深的判断难以定位和修改。 增强扩展性:模块化和面向对象的设计模式能够更轻松地扩展和复用代码。 便于测试:分支逻辑过多时,编写全面的测试用例变得繁琐,容易遗漏边界情况。 常见解决方案1. 使用策略模式策略模式将一系列算法封装为独立的策略对象,并通过上下文类动态选择执行。这样可以将 if-else 判断分散到不同的策略中。 示例代码: 1234567891011121314151617181920// 定义策略函数const strategies = { add: (a, b) => a...
JavaScript作用域和闭包
在本文中,笔者将用通俗的语言和简单的代码,介绍以下几种概念: 变量提升 this的使用场景 作用域 闭包的应用 文章最后最后还有一个例题~ 变量提升首先我们要知道,js的执行顺序是由上到下的,但这个顺序,并不完全取决于你,因为js中存在变量的声明提升。 这里比较简单,直接上代码 123456789console.log(a) //undefinedvar a = 100fn('zhangsan')function fn(name){ age \= 20 console.log(name, age) //zhangsan 20 var age} 结果 打印a的时候,a并没有声明,为什么不报错,而是打印undefined。 执行fn的时候fn并没有声明,为什么fn的语句会执行? 这就是变量的声明提升,代码虽然写成这样,但其实执行顺序是这样的。 1234567891011var afunction fn(name){ age \= 20 console.log(name,...
JavaScript 的类与继承
类的声明与实例化类的声明一般有两种方式 1234567891011//类的声明var Animal = function () { this.name = 'Animal';};//ES6中类的声明class Animal2 { constructor () { this.name = 'Animal2'; }} 实例化就比较简单,直接用 new 运算符 123new Animall()new Animal2() 这些比较简单,简单介绍一下就可以了。接下来,介绍本文的重点内容,继承。 如何实现继承实现继承的方式主要有两种: 第一种借助构造函数实现继承 先看个了例子 12345678function Parent1 () { this.name = 'parent1';}function Child1 () { Parent1.call(this);...
详谈JavaScript原型链
创建对象的方法在了解原型链之前,首先先了解一下创建对象的几种方式,主要有以下三种 代码: 123456789101112131415<script type="text/javascript"> // 第一种方式:字面量 var o1 = {name: 'o1'} var o2 = new Object({name: 'o2'}) // 第二种方式:构造函数 var M = function (name) { this.name = name; } var o3 = new M('o3') // 第三种方式:Object.create var p = {name: 'p'} var o4 = Object.create(p) console.log(o1) console.log(o2) console.log(o3) ...
三栏布局的五种解决方案及优缺点
问题假设高度已知,请写出三栏布局,左栏、右栏宽度300px,中间宽度自适应。 这道题本身的难度并不大,我们在布局页面的时候,写个三栏布局还是挺简单的。但是如果在面试的时候遇到这道题,就没有那么简单了。看似简单的一道题,想把它答好是不简单的。往往越简单的题越不好答。如果看到这题只想到了浮动和绝对定位,那这题你连及格都及格不了。 样式下面是5种三栏布局的方法。在写布局代码之前,先写两段公共的样式,此段写在头部。 12345678910<style media="screen"> html *{ padding: 0; margin: 0; } .layout article div{ min-height: 100px; } </style> 1. 浮动布局12345678910111213141516171819202122232425262728<!--浮动布局 --> ...
深入理解CSS盒模型
前言如果你在面试的时候面试官让你谈谈对盒模型的理解,你是不是不知从何谈起。这种看似简单的题其实是最不好答的。 下面本文章将会从以下几个方面谈谈盒模型。 基本概念:标准模型 和IE模型 CSS如何设置这两种模型 JS如何设置获取盒模型对应的宽和高 实例题(根据盒模型解释边距重叠) BFC(边距重叠解决方案) 基本概念盒模型的组成大家肯定都懂,由里向外content,padding,border,margin. 盒模型是有两种标准的,一个是标准模型,一个是IE模型。 从上面两图不难看出在标准模型中,盒模型的宽高只是内容(content)的宽高, 而在IE模型中盒模型的宽高是内容(content)+填充(padding)+边框(border)的总宽高。 css如何设置两种模型这里用到了CSS3 的属性 box-sizing 12345/\* 标准模型 \*/box-sizing:content-box;...
深入解析 Cookie、sessionStorage 和 localStorage 的区别
在前端开发中,Cookie、sessionStorage 和 localStorage 是我们经常使用的存储方式。它们的区别看似简单,但如果你能理解它们的核心特性、性能影响以及安全风险,你就能在面试或实际开发中游刃有余。 1. 容量限制与数据格式 存储方式 容量限制 数据格式 Cookie 4KB 只能存储字符串 sessionStorage 约 5MB 只能存储字符串(可转换为 JSON) localStorage 约 5MB 只能存储字符串(可转换为 JSON) 🔹 扩展点: 虽然 sessionStorage 和 localStorage 只能存储字符串,但我们可以使用 JSON.stringify() 存入对象,取出时用 JSON.parse() 还原。 1234const user = { name: "张三", age: 25 };localStorage.setItem("user", JSON.stringify(user));const storedUser =...