JavaScript 对象设计与 DOM 安全:封装、继承和随机布局
本文目录
面向对象是一种组织状态与行为的方式,不是 JavaScript 唯一的编程范式。JavaScript 支持原型委托,也提供 class 语法;函数式组合、模块和普通对象同样常见。选择设计时看状态归属、复用边界和测试成本,不要为了“像 Java”而把所有功能包进类。
从表单数据安全地生成表格
动态插入用户昵称和留言时,使用 createElement、textContent 和受控属性;不要把输入拼到 innerHTML。先校验字段长度、空白和业务规则,服务端还要重复校验并执行授权。
function appendMessage(tableBody, nickname, message) {
const row = document.createElement('tr');
const nameCell = document.createElement('td');
const messageCell = document.createElement('td');
nameCell.textContent = nickname.trim().slice(0, 40);
messageCell.textContent = message.trim().slice(0, 2000);
row.append(nameCell, messageCell);
tableBody.append(row);
}
如果内容需要链接或富文本,先定义允许的元素、属性和 URL 协议,再交给可信 HTML sanitizer;普通文本不需要 HTML 解析器。表格要有 caption、thead、th 和适当的 scope,键盘用户与屏幕阅读器才能理解结构。
封装、继承与拷贝的真实含义
封装是隐藏变化点并提供明确接口,不只是把重复代码放进函数。原型可共享方法,属性初始化仍要发生在每个实例上。现代 class 的方法位于 prototype;继承关系应保持简单,并考虑用组合替代层层改写原型指向。
拷贝对象时先区分浅拷贝和深拷贝:Object.assign 与展开语法只复制一层,嵌套对象仍共享。structuredClone 支持结构化克隆类型,但不能克隆函数、DOM 节点等任意值,也不能替代业务 DTO 的字段白名单。不要用 for...in 盲目复制对象。
const source = { profile: { theme: 'light' } };
const shallow = { ...source };
shallow.profile.theme = 'dark';
source.profile.theme; // 'dark':嵌套引用共享
const isolated = structuredClone(source);
在网格中放置随机目标
贪吃蛇食物或棋盘目标应按格子生成坐标,避免 CSS 像素随机后落在半格。随机整数函数采用左闭右开区间;地图尺寸先换算为格子数,再从合法索引取值。放置前排除蛇身、障碍和不可用格子;没有空格时应结束游戏或返回“无位置”,不能无限重试。
function randomIndex(length) {
if (!Number.isInteger(length) || length <= 0) throw new RangeError('length 必须大于 0');
return Math.floor(Math.random() * length);
}
function chooseFreeCell(cells, occupiedKeys) {
const free = cells.filter((cell) => !occupiedKeys.has(cell.x + ':' + cell.y));
return free.length ? free[randomIndex(free.length)] : null;
}
Math.random 不能用于安全随机数。地图缩放或容器尺寸改变时,重新计算网格边界并清理旧元素;不要把 DOM 节点、坐标和游戏规则混在同一个全局对象里。
验收清单
- 用户输入能否被当作 HTML 执行?普通文本是否只进 textContent?
- 对象复制后哪些嵌套字段仍共享引用?
- 继承是否真的比组合简单,父构造函数是否被重复执行?
- 随机坐标是否落在网格内并避开已占用位置?
- 无空闲格、空输入和过长文本是否有明确结果?
参考:MDN DOM createElement、MDN Node.textContent、MDN structuredClone、MDN prototype chain、OWASP DOM XSS Prevention。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。