【发布时间】:2019-07-30 16:23:27
【问题描述】:
我正在尝试在JavaScript30 上完成一个练习。我想知道为什么我想出的解决方案不起作用。
这个想法很简单。您有一个网页,其中视频的持续时间存储在列表中,如下所示:
<ul class="videos">
<li data-time="5:43">
Video 1
</li>
<li data-time="2:33">
Video 2
</li>
</ul>
列表中实际上有 58 个项目。练习是统计所有视频的总时长(换句话说,获取列表中包含的所有时长的总和)。
我有课程制作者解决方案的代码,它采用了与我的解决方案不同的路径。在我创建“时间”类时,它将持续时间存储为秒。我了解此解决方案,但我想了解为什么我的解决方案不起作用。
课程提供的解决方案:
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
const seconds = timeNodes
.map(node => node.dataset.time)
.map(timeCode => {
const [mins, secs] = timeCode.split(':').map(parseFloat);
return (mins * 60) + secs;
})
.reduce((total, vidSeconds) => total + vidSeconds);
let secondsLeft = seconds;
const hours = Math.floor(secondsLeft / 3600);
secondsLeft = secondsLeft % 3600;
const mins = Math.floor(secondsLeft / 60);
secondsLeft = secondsLeft % 60;
console.log(hours, mins, secondsLeft);
我的(尚未运行的)解决方案:
function Time(hours = 0, minutes = 0, seconds = 0) {
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.addTime = function(hours = 0, minutes = 0, seconds = 0) {
const ajout = new Time(hours, minutes, seconds);
this.add(ajout);
}
this.add = function(ajout) {
let surplus = 0;
// seconds
this.seconds += ajout.seconds;
while (this.seconds >= 60) {
this.seconds -= 60;
surplus++;
}
// minutes
this.minutes += ajout.minutes + surplus;
surplus = 0;
while (this.minutes >= 60) {
this.minutes -= 60;
surplus++;
}
// hours
this.hours += ajout.hours + surplus;
}
this.toString = function() {
return `${this.hours} h ${this.minutes} min ${this.seconds} s`;
}
}
function stringToTime (str) {
let h, m, s = 0;
const arr = str.split(':');
while (arr.length > 3) {
arr.shift();
}
if (arr.length == 3) {
h = parseInt(arr.shift());
}
if (arr.length == 2) {
m = parseInt(arr.shift());
}
if (arr.length == 1) {
s = parseInt(arr.shift());
}
return new Time(h, m, s);
}
//const reducerForTime = (accumulator, currentValue = new Time()) => accumulator.add(currentValue) || new ();
const reducerForTime = (accumulator, currentValue = new Time()) =>
{
console.log(currentValue);
//console.log(`accumulator = ${accumulator.toString()}; currentValue = ${currentValue.toString()}`);
accumulator.add(currentValue);
console.log(`accumulator after adding = ${accumulator.toString()}`);
};
const videos = document.querySelectorAll('ul.videos li');
let videoTimes = [];
for (let i = 0; i < videos.length; i++) {
videoTimes.push(stringToTime(videos[i].dataset.time));
}
console.log(videoTimes.reduce(reducerForTime).toString());
错误如下: Uncaught TypeError: Cannot read property 'add' of undefined
您会注意到我在 reducer 函数中添加了两个“console.log”行,以尝试找出问题所在。
我现在得到这个控制台输出:
Time {hours: 0, minutes: 2, seconds: 33, addTime: ƒ, add: ƒ, …}
accumulator after adding = 0 h 8 min 16 s
Time {hours: 0, minutes: 3, seconds: 45, addTime: ƒ, add: ƒ, …}
Uncaught TypeError: Cannot read property 'add' of undefined
at reducerForTime (index-START.html:239)
at Array.reduce (<anonymous>)
at index-START.html:248
reducerForTime @ index-START.html:239
(anonymous) @ index-START.html:248
它所指的行是 248 和 239。 248 行是调用reduce 函数的行。 239 行是带有accumulator.add(currentValue); 的行。我不知道为什么它不起作用,因为根据我的理解,累加器应该保持从一个迭代到下一个迭代,因此应该是一个 Time 对象,因此应该有一个“添加”属性。为什么错误消息告诉我它未定义?
【问题讨论】:
-
在
reducerForTime函数的末尾尝试return accumulator;
标签: javascript arrays class