如何从外部JS文件中访问嵌套数组中的项目?

发布于 2025-01-19 17:06:01 字数 3530 浏览 1 评论 0原文

我正在自己的网站上充当简历和投资组合,这是一种显示我的网页设计技能的有趣方式。它的目的是使用JavaScript通过用作数据库的数组来使用我的每个作业,关键技能,资格等来填充网页。

添加了两个脚本标签

<script type="module" src="js/database_career.js" defer></script>
<script type="module" src="js/script.js" defer></script>

在我的头部部分中,我在database_career.js文件中

function Job(title,company,location,date,summary,details) {
  this.title = title;
  this.company = company;
  this.location = location;
  this.date = date;
  this.summary = summary;
  this.details = details;
}

,我创建了一个具有作业详细信息的类构造函数作为其对象属性,并且在同一文件中,这是我想要的所有作业的(示例)填充我的网页。

const JOBS = [
  new Job(
    "Job Title",
    "Company",
    "Location",
    "Month 20XX ~ Now",
    "Insert Job Summary Here",
    ["Bullet Point for notable task or accomplishment 1",
    "Bullet Point for notable task or accomplishment 2",
    "Bullet Point for notable task or accomplishment 3"]
  ),
  new Job()
];

现在,这是我到目前为止在主脚本文件中编码的内容。

    import JOBS from "./database_career.js";
        
            // Populate the Career Section
            const myCareer = document.querySelector("#work");
              const jobSection = document.createElement("div");
                jobSection.classList.add("content-wrap", "clearfix");
            
                const jobsHeading = document.createElement("h2");
                const jobsHeading_content = `<i class="fas fa-briefcase" aria-hidden="true"></i>Work Experience`;
                jobsHeading.innerHTML = jobsHeading_content;
                jobSection.append(jobsHeading);
        
        for (let i=0;i<JOBS.length;i++) {
                const jobEntry = document.createElement("div");
                  jobEntry.classList.add("entry");
        
                const jobContent_narrow = `
                  <div class="col-narrow">
                    <h3>${JOBS[i].title}</h3>
                    <p class="uppercase">${JOBS[i].company}, ${JOBS[i].location}</p>
                    <p>${JOBS[i].date}</p>
                  </div>`;
        
        const jobContent_wide = `
                  <div class="col-wide description">
                  <p>${JOBS[i].summary}</p>`;
        
// Here's where I'm stuck. 
// I managed to get the rest of the job details, shown above, displaying correctly.
// I want to show the extra details in an unordered list but I was unable to access
// any individual items in the details array

// I could only show the full array itself but
// manipulating the array itself seems to be impossible
// I keep getting the following error
// script.js:49 Uncaught TypeError: Cannot read properties of undefined (reading 'length') at script.js:49:42

        const jobDetails = document.createElement("ul");
          for (let e=0;e<JOBS[i].details.length;e++) {
            let listItem = document.createElement("li");
            let item = `<li>${JOBS[i].details[e]}</li>`;
            jobDetails.append(item);
          }
        
                const jobDetails_end = `
                </div>`;
        
                jobEntry.innerHTML = jobContent_narrow + jobContent_wide + jobDetails_end;
                jobSection.append(jobEntry);
              }
        
            myCareer.append(jobSection);

如果您错过了评论,我正在尝试将每个作业中包含的详细信息数组中的项目添加为无序列表中的项目符号,但无法直接访问它们。相反,我可以显示完整的阵列本身。

任何帮助和建议都将不胜感激,如果需要,我将提供任何进一步的信息。

谢谢。

I am working on my own website that acts as a CV and portfolio, a fun way to display my web design skills. The aim of it is to use JavaScript to populate the webpage with each of my jobs, key skills, qualifications, etc. from arrays used as a database.

In my head section, I added two script tags

<script type="module" src="js/database_career.js" defer></script>
<script type="module" src="js/script.js" defer></script>

In the database_career.js file, I created a class constructor with the job details as its object properties

function Job(title,company,location,date,summary,details) {
  this.title = title;
  this.company = company;
  this.location = location;
  this.date = date;
  this.summary = summary;
  this.details = details;
}

And in that same file, here's (a sample of) an array of all the jobs I want to populate my web page with.

const JOBS = [
  new Job(
    "Job Title",
    "Company",
    "Location",
    "Month 20XX ~ Now",
    "Insert Job Summary Here",
    ["Bullet Point for notable task or accomplishment 1",
    "Bullet Point for notable task or accomplishment 2",
    "Bullet Point for notable task or accomplishment 3"]
  ),
  new Job()
];

Now here's what I coded in the main script.js file so far.

    import JOBS from "./database_career.js";
        
            // Populate the Career Section
            const myCareer = document.querySelector("#work");
              const jobSection = document.createElement("div");
                jobSection.classList.add("content-wrap", "clearfix");
            
                const jobsHeading = document.createElement("h2");
                const jobsHeading_content = `<i class="fas fa-briefcase" aria-hidden="true"></i>Work Experience`;
                jobsHeading.innerHTML = jobsHeading_content;
                jobSection.append(jobsHeading);
        
        for (let i=0;i<JOBS.length;i++) {
                const jobEntry = document.createElement("div");
                  jobEntry.classList.add("entry");
        
                const jobContent_narrow = `
                  <div class="col-narrow">
                    <h3>${JOBS[i].title}</h3>
                    <p class="uppercase">${JOBS[i].company}, ${JOBS[i].location}</p>
                    <p>${JOBS[i].date}</p>
                  </div>`;
        
        const jobContent_wide = `
                  <div class="col-wide description">
                  <p>${JOBS[i].summary}</p>`;
        
// Here's where I'm stuck. 
// I managed to get the rest of the job details, shown above, displaying correctly.
// I want to show the extra details in an unordered list but I was unable to access
// any individual items in the details array

// I could only show the full array itself but
// manipulating the array itself seems to be impossible
// I keep getting the following error
// script.js:49 Uncaught TypeError: Cannot read properties of undefined (reading 'length') at script.js:49:42

        const jobDetails = document.createElement("ul");
          for (let e=0;e<JOBS[i].details.length;e++) {
            let listItem = document.createElement("li");
            let item = `<li>${JOBS[i].details[e]}</li>`;
            jobDetails.append(item);
          }
        
                const jobDetails_end = `
                </div>`;
        
                jobEntry.innerHTML = jobContent_narrow + jobContent_wide + jobDetails_end;
                jobSection.append(jobEntry);
              }
        
            myCareer.append(jobSection);

In case you missed the comments, I'm trying to add items from the details array contained in each job as bullet points in an unordered list but have been unable to access them directly. Instead I could display the full array itself.

Any help and advice would be much appreciated and I'll provide any further information if needed.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

痴情换悲伤 2025-01-26 17:06:01

我看到您的函数将详细信息初始化为 this.details,因此如果您不传递该参数,它可能会被初始化为未定义。

你确定每个工作都有详细信息吗?即使是空数组列表?

抛出的错误告诉您他正在尝试获取第一个循环中每个作业的详细信息的长度,但未定义,并且调用 undefined.length 会抛出该异常

I see your function initializes the details as this.details, so it could potentially be initialized as undefined if you don't pass that parameter.

Are you sure every single job has details? even as empty array lists?

The error thrown tells you he's trying to get the length of details of every job in the first loop, but got undefined, and calling undefined.length throws that exception

ˉ厌 2025-01-26 17:06:01

我认为该问题是由 database_career.js 上的以下行引起的:

  ),
  new Job() // <---
];

您在其中实例化了一个新作业,并将 details 设置为 undefined
因此,以下行:

for (let e=0;e<JOBS[i].details.length;e++) 

调用不安全,因为 .length 不存在于 undefined 字段中。


我建议将此函数更改为类似以下内容:

function Job({ title, company, location, date, summary, details = [] } = {}) {
// ...

这使用 解构赋值默认参数(查看文档以了解更多信息它们并查看支持哪些浏览器)并且允许有类似的内容:

const JOBS = [
  new Job({
    title: "Job title",
    company: "Job company",
    // ...
    details: ["1", "2"]
  }),
  new Job(),
];

其中 job.details 将始终初始化为空数组,因此可以安全地循环而无需显式检查首先是未定义

我建议的另一件事是重构 js/script.js 并创建一些小的可重用函数,例如

function render() {
  // ..
  for (let i=0; i< JOBS.length;i++ ) {
    renderJob(JOBS[i]);
  }
}

function renderJob(job) {
  // ...
  renderJobDetails(job.details);
}

function renderJobDetails(details) {
 // ...
}

render();

提高可读性。

如果您再次遇到困难,您可能需要看看这篇文章:

https://javascript.info/debugging- chrome

了解如何使用浏览器调试器工具并更好地理解为什么您的代码不能按预期工作。

I believe that the problem is caused by the following line on database_career.js:

  ),
  new Job() // <---
];

where you instantiate a new job with details set to undefined.
Therefore the following line:

for (let e=0;e<JOBS[i].details.length;e++) 

is not safe to call because .length does not exist on undefined fields.


What I would recommend is to change this function to something like:

function Job({ title, company, location, date, summary, details = [] } = {}) {
// ...

This uses the destructuring assignment and default parameters (check the docs to learn more about them and see which browsers are supported) and would allow to have something like:

const JOBS = [
  new Job({
    title: "Job title",
    company: "Job company",
    // ...
    details: ["1", "2"]
  }),
  new Job(),
];

where job.details will always be initialised to an empty array and therefore will be safe to loop without explicitly checking for undefined first.

Another thing that I would recommend is to refactor js/script.js and create some small reusable functions, e.g.

function render() {
  // ..
  for (let i=0; i< JOBS.length;i++ ) {
    renderJob(JOBS[i]);
  }
}

function renderJob(job) {
  // ...
  renderJobDetails(job.details);
}

function renderJobDetails(details) {
 // ...
}

render();

to improve readability.

If you get stuck again you might want to have a look at this article:

https://javascript.info/debugging-chrome

to learn how to use the browser debugger tool and better understand why your code does not work as expected.

小苏打饼 2025-01-26 17:06:01

嵌套模板文字

<ul>${job.details.map(detail => `<li>${detail}</li>`).join("")}</ul>

您可以像这样

document.querySelector("#work").innerHTML = `
  <div class="content-wrap clearfix">
    <h2><i class="fas fa-briefcase" aria-hidden="true"></i>Work Experience</h2>
  ${JOBS.map(job => `
    <div class="entry">
      <div class="col-narrow">
        <h3>${job.title}</h3>
        <p class="uppercase">${job.company}, ${job.location}</p>
        <p>${job.date}</p>
      </div><div class="col-wide description">
        <p>${job.summary}</p>
        <ul>${job.details.map(detail => `<li>${detail}</li>`).join("")}</ul>
      </div>
    </div>`).join("")}
  </div>`
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />


<div id="work"></div>

<script>
function Job(title, company, location, date, summary, details) {
  this.title = title;
  this.company = company;
  this.location = location;
  this.date = date;
  this.summary = summary;
  this.details = details;
}


const JOBS = [
  new Job(
    "Job Title",
    "Company",
    "Location",
    "Month 20XX ~ Now",
    "Insert Job Summary Here", ["Bullet Point for notable task or accomplishment 1",
      "Bullet Point for notable task or accomplishment 2",
      "Bullet Point for notable task or accomplishment 3"
    ]
  ),
  new Job(
    "Job Title",
    "Company",
    "Location",
    "Month 20XX ~ Now",
    "Insert Job Summary Here", ["Bullet Point for notable task or accomplishment 1",
      "Bullet Point for notable task or accomplishment 2",
      "Bullet Point for notable task or accomplishment 3"
    ]
  ),

];
</script>

You can nest the template literals

<ul>${job.details.map(detail => `<li>${detail}</li>`).join("")}</ul>

like this

document.querySelector("#work").innerHTML = `
  <div class="content-wrap clearfix">
    <h2><i class="fas fa-briefcase" aria-hidden="true"></i>Work Experience</h2>
  ${JOBS.map(job => `
    <div class="entry">
      <div class="col-narrow">
        <h3>${job.title}</h3>
        <p class="uppercase">${job.company}, ${job.location}</p>
        <p>${job.date}</p>
      </div><div class="col-wide description">
        <p>${job.summary}</p>
        <ul>${job.details.map(detail => `<li>${detail}</li>`).join("")}</ul>
      </div>
    </div>`).join("")}
  </div>`
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />


<div id="work"></div>

<script>
function Job(title, company, location, date, summary, details) {
  this.title = title;
  this.company = company;
  this.location = location;
  this.date = date;
  this.summary = summary;
  this.details = details;
}


const JOBS = [
  new Job(
    "Job Title",
    "Company",
    "Location",
    "Month 20XX ~ Now",
    "Insert Job Summary Here", ["Bullet Point for notable task or accomplishment 1",
      "Bullet Point for notable task or accomplishment 2",
      "Bullet Point for notable task or accomplishment 3"
    ]
  ),
  new Job(
    "Job Title",
    "Company",
    "Location",
    "Month 20XX ~ Now",
    "Insert Job Summary Here", ["Bullet Point for notable task or accomplishment 1",
      "Bullet Point for notable task or accomplishment 2",
      "Bullet Point for notable task or accomplishment 3"
    ]
  ),

];
</script>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文