js中map用法与foreach用法之差异

涉及到的代码如下:
  const urls = [
      'http://192.168.15.149:3000/d/000000039/postgresql-database?orgId=1&refresh=10s&from=now-6h&to=now',
      'http://192.168.15.149:3000/d/TgmJnqnnk/minio-dashboard?orgId=1&var-scrape_jobs=minio-cluster',
      'http://192.168.15.149:3000/d/TgmJnnqn2k/minio-node-dashboard?orgId=1&var-DS_PROMETHEUS=DS_PROMETHEUS&var-scrape_jobs=minio-node&var-server=minio1:9000',
      'http://192.168.15.149:3000/d/TgmJnqnnk2/minio-bucket-dashboard?orgId=1&var-scrape_jobs=minio-bucket',
      'http://192.168.15.149:3000/d/rYdddlPWk/node-exporter-full?orgId=1&refresh=1m&var-ds_prometheus=DS_PROMETHEUS&var-job=node-exporter&var-nodename=10eb0cd53f3b&var-node=node-exporter:9100',
      'http://192.168.15.66:2888/intelligenceVisual/standardization?visualModelType=0',
      'http://www.baidu.com',
      'http://www.baidu.com'
    ];
 
const tiles = urls.map(u => {
      const a = document.createElement('a');
      a.href = u;
      a.className = 'tile';

      const f = document.createElement('iframe');
      f.src = u;

      const label = document.createElement('span');
      label.className = 'label';
      label.textContent = new URL(u).hostname;//label标签显示内容做了截取
      label.title = u;

      a.appendChild(f);//<a>里面套<iframe>
      a.appendChild(label);//<a>里面套<span>
      container.appendChild(a);//<grid>里面套<a>
     
      //grid内的各个<a>区域增加点击事件
      a.addEventListener('click', e => {
        e.preventDefault();
        openModal(u);//调用弹出框页面函数
      });

      return { a, f };
    });

map 是什么

- 数组方法,用于“把一个数组转成另一个数组”
- 对原数组的每个元素调用一次回调函数,并用回调的返回值组成一个“新数组”。
- 语法要点:map 不修改原数组;如果回调不返回值,生成的新数组元素就是 undefined。

这段 map 在做什么

- 输入:urls(字符串数组,每个是一个页面地址)。
- 过程:对每个 url
  - 创建一个可点击的格子 a(父元素)。
  - 创建一个缩略图 iframe(子元素),设置 src 为该 url。
  - 创建一个左下角标签 label,文本为该 url 的域名。
  - 把 iframe 和 label 放进格子,再把格子加入网格容器。
  - 绑定点击事件,阻止默认跳转,改为打开弹窗显示该 url。
- 输出:返回一个对象 {a, f},包含“格子元素”和“缩略图 iframe”的引用。最终得到 tiles 数组,长度与 urls 一致

 

为什么用 map,而不是 forEach

- map 的“巧妙点”在于:一边“遍历构建 DOM”,一边“生成一个结构化的引用数组”,方便后续操作。
- 后续的 fitCover 用到了 tiles:tiles.forEach(({a, f}) => { … }),对每个格子计算缩放与居中。若用 forEach,就需要另建数组来保存 a 和 f。
- map 的返回值就是“派生数据模型”:把“原始数据(url)”自然地变成“视图模型({a,f})”。这种“数据 → 视图”的转换非常直观。
- 简洁与可读性:创建、注册事件、收集引用这三件事集中在同一块代码里完成,逻辑清晰。

对比示例

- 用 forEach 实现同样功能,需要手动维护引用数组:

const tiles = [];
urls.forEach(u => {
const a = document.createElement('a');
const f = document.createElement('iframe');
// ...同样的创建与绑定
tiles.push({ a, f });
});

- 用 map 更自然(把每个 url 映射为 {a,f}):

const tiles = urls.map(u => {
const a = document.createElement('a');
const f = document.createElement('iframe');
// ...同样的创建与绑定
return { a, f };
});

两者都能做到,但 map 强调“变换并返回结果”,forEach 强调“遍历产生副作用”。

posted @ 2026-01-07 11:31  上清风  阅读(4)  评论(0)    收藏  举报