JavaScript 高频问题:数组回调、变量作用域与跨域边界
本文目录
旧问题集里有些区分仍然有用,但“某 API 能跨域”“CORS 是授权”“所有数组方法都会执行每一项”都不成立。以下把容易混淆的判断改成可验证的规则。
map、filter、find、some 与 every
map 对元素做一对一变换并返回新数组;只执行副作用时用循环或 forEach 更清楚。filter 保留所有通过条件的元素;find 返回第一个匹配值,找不到为 undefined;findIndex 返回索引,找不到为 -1。some 判断至少一个,every 判断全部;两者会在答案确定后提前停止。空数组上 some 为 false,every 为 true,这是逻辑上的存在/全称判断。
多数迭代方法不修改原数组,但回调仍可以修改元素对象或外部状态。稀疏数组的空槽行为也因方法而异。回调应保持简单,把网络请求和状态变更单独设计,不要把 map(async ...) 误认为它会等待任务完成。
声明、提升与函数
var 声明会在相应函数或脚本作用域内表现出提升,初始化仍按执行顺序发生;let / const 有块级作用域和 TDZ。函数声明与函数表达式的创建时机不同;不要在条件块中依赖旧浏览器对函数声明的差异行为。现代模块使用严格模式和模块级作用域,不应把经典脚本的全局对象口诀套用到所有代码。
同源策略和 CORS
同源通常由协议、主机名和端口共同决定。浏览器仍允许某些跨源导航或嵌入资源,但限制脚本读取另一个 origin 的响应;“图片能显示”并不代表 JavaScript 能读取像素或响应内容。
Fetch/XHR 的 CORS 是服务器通过响应头告诉浏览器是否允许指定 origin 读取响应。非简单请求可能先发送 OPTIONS 预检;服务器需正确处理方法、请求头和 origin。携带凭据时必须显式允许凭据,且不能把通配 origin 当作授权规则。CORS 不校验用户身份、不阻止 curl/服务器端请求,也不能替代 CSRF 防护、认证和业务权限。
JSONP 依赖 script 标签执行远端返回的 JavaScript,通常只适合旧式 GET 兼容;它无法像 JSON 一样安全地仅解析数据,远端脚本拥有页面同源脚本能力。新接口应优先采用 HTTPS API、正确 CORS 配置和常规认证。不要用关闭浏览器同源策略的启动参数“解决”问题,那会把整个浏览器会话暴露给恶意页面。
async function fetchPublicProfile(url) {
const response = await fetch(url, {
mode: 'cors',
credentials: 'omit',
});
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}
前端的 mode: 'cors' 不能自行授予权限;服务器响应头才决定浏览器是否向脚本暴露结果。若预检失败,先在网络面板查看 OPTIONS 请求和响应,再检查反向代理是否丢了允许头;不要添加任意 origin 回显或把敏感端点改成公开读取。
排查清单
- 先写出目标方法应返回值、布尔值、索引还是新集合,再选择数组 API。
- 分别测试空数组、无匹配、重复匹配、空槽与异步回调。
- 确认脚本是 module 还是 classic script,并检查目标浏览器的词法作用域支持。
- 跨域错误时检查 origin 三元组、OPTIONS、允许方法/请求头、凭据策略和代理响应。
- 把 CORS、CSRF、认证和资源权限分开建模,不以隐藏报错代替授权设计。
参考:MDN Array iterative methods、MDN let、MDN Same-origin policy、MDN CORS、MDN Using Fetch、OWASP CSRF Prevention。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。