我有一个包含年份和发布标识符的嵌套对象。如何按年份列出出版物,最晚到最早?我读到here,从ES6开始,对象的顺序是可预测的。在我的代码中,我有一个函数,它生成年份的下拉列表(addOption),而另一个函数则用选定年份或所有年份的出版物填充div。如果用户选择了所有年份,则会按从最早到最新(升序)的顺序显示出版物,但我希望出版物以倒序显示。是否有内置的JavaScript对象方法可以做到这一点?
const testPubs = {
2019 : {
'19-6N': {
'author' : 'jimbo',
'title' : 'test title'
},
'19-7N': {
'author' : 'jimmy',
'title' : 'test title 2'
}
},
2018 : {
'18-6N': {
'author' : 'joey',
'title' : 'test title'
},
'18-7N': {
'author' : 'jeffy',
'title' : 'test title 2'
}
},
2017 : {
'17-6N': {
'author' : 'bob',
'title' : 'test title'
},
'17-7N': {
'author' : 'bobby',
'title' : 'test title 2'
}
},
}
const startYear = 1984;
const currentYear = new Date().getFullYear();
function addOption() { // adds years to dropdown menu
const select = document.querySelector('#selectYears');
let blank_option = document.createElement("option");
blank_option.setAttribute("selected", true);
blank_option.setAttribute("disabled", true);
blank_option.textContent = `Year`;
select.appendChild(blank_option);
for (let i = currentYear; i >= startYear; i--){
let option = i;
let el = document.createElement("option");
el.textContent = option;
select.appendChild(el);
}
const allYears = document.createElement("option");
allYears.textContent = `All Years`;
select.appendChild(allYears)
}
addOption(); // add years dropdown
function populatePubs(year){
const pubsForYear = document.querySelector("#pubsByYear");
pubsByYear.class = year;
while (pubsForYear.firstChild){
pubsByYear.removeChild(pubsByYear.firstChild);
}
if (year in testPubs){
for (let pub in testPubs[year]){ // add publications for specified year
let doc = document.createElement("div");
doc.id = pub;
doc.textContent = `${testPubs[year][pub].author} - ${testPubs[year][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
} else if (year === 'All Years') { // need to ensure order of object is descending
for (let yr in testPubs){ // add publications for all years
const yearHeader = document.createElement("h4");
yearHeader.innerText = yr;
pubsByYear.appendChild(yearHeader);
if (typeof testPubs[yr] === 'object'){
for (let pub in testPubs[yr]) {
pubsByYear.class = `All Years`;
const doc = document.createElement("div");
doc.id = testPubs[yr][pub];
doc.textContent = `${testPubs[yr][pub].author} - ${testPubs[yr][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
}
}
}
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Test Publications by Year</title>
<body>
<!-- years dropdown -->
<select id="selectYears" onchange="populatePubs(this.value)"></select>
<!-- display current year -->
<div id="pubsByYear" class="year"></div>
<script src="script.js"></script>
</body>
</html>
您可以仅将内置的反向方法与Object.keys方法结合使用:
function populatePubs(year) {
const pubsForYear = document.querySelector("#pubsByYear");
pubsByYear.class = year;
while (pubsForYear.firstChild) {
pubsByYear.removeChild(pubsByYear.firstChild);
}
if (year in testPubs) {
for (let pub in testPubs[year]) { // add publications for specified year
let doc = document.createElement("div");
doc.id = pub;
doc.textContent = `${testPubs[year][pub].author} - ${testPubs[year][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
} else if (year === 'All Years') { // need to ensure order of object is descending
const years = Object.keys(testPubs).reverse();
for (let yr of years) { // add publications for all years
const yearHeader = document.createElement("h4");
yearHeader.innerText = yr;
pubsByYear.appendChild(yearHeader);
if (typeof testPubs[yr] === 'object') {
for (let pub in testPubs[yr]) {
pubsByYear.class = `All Years`;
const doc = document.createElement("div");
doc.id = testPubs[yr][pub];
doc.textContent = `${testPubs[yr][pub].author} - ${testPubs[yr][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
}
}
}
}