Chương trình của bạn không hoạt động vì, a
có giá trị tích lũy từ cuộc gọi hàm trước đó. Lần đầu tiên, hai giá trị đầu tiên của mảng sẽ được sử dụng. Vì vậy, sum
sẽ trở thành 17
(2 + 15
). Vì bạn không trả lại bất cứ thứ gì từ hàm này, theo mặc định, undefined
sẽ được trả lại và sẽ được sử dụng làm giá trị cho a
, trong cuộc gọi tiếp theo. Vì vậy, việc đánh giá đi như thế này
a: 2, b: 15 => 17
a: undefined, b: 7 => NaN
Vì vậy, sum
sẽ có NaN
, vì undefined + 7
làm cho nó như vậy. Bất kỳ thao tác số nào trên NaN
, sẽ luôn cung cấp NaN
, đó là lý do tại sao NaN/this.length
, cung cấp cho bạn NaN
. Bạn có thể sửa chương trình của mình, chỉ bằng cách trả về giá trị hiện tại của sum
bất cứ khi nào hàm được gọi, để cuộc gọi hàm tiếp theo, a
sẽ có giá trị tích lũy thích hợp.
Array.prototype.average = function() {
var sum = 0;
this.reduce(function(a, b) {
sum = a + b;
return sum;
});
return sum/this.length;
};
Nhưng chúng tôi không tận dụng sức mạnh và tính linh hoạt của reduce
tại đây. Dưới đây là hai điểm quan trọng cần xem xét khi sử dụng reduce
.
reduce
chấp nhận tham số thứ hai cho biết giá trị ban đầu sẽ được sử dụng. Bất cứ khi nào có thể, hãy xác định điều đó.
Tham số đầu tiên trong hàm được chuyển đến reduce
tích lũy kết quả và cuối cùng sẽ được trả lại, hãy tận dụng điều đó. Không cần phải sử dụng một biến riêng biệt để theo dõi kết quả.
Vì vậy, mã của bạn sẽ trông tốt hơn như thế này
Array.prototype.average = function() {
var sum = this.reduce(function(result, currentValue) {
return result + currentValue
}, 0);
return sum/this.length;
};
console.log([2, 15, 7].average());
# 8
reduce
thực sự hoạt động như thế này. Nó lặp qua mảng và chuyển giá trị hiện tại làm tham số thứ hai cho hàm và kết quả được tích lũy hiện tại làm tham số đầu tiên và giá trị được trả về từ hàm sẽ được lưu trữ trong giá trị tích lũy.Vì vậy, số tiền thực sự tìm thấy như thế này
result: 0 , currentValue: 2 => 2 (Initializer value `0`)
result: 2 , currentValue: 15 => 17
result: 17, currentValue: 7 => 24
Kể từ khi nó chạy ra các giá trị từ mảng, 24
sẽ được trả lại như là kết quả của reduce
, đó sẽ được lưu trữ trong sum
.
Từ mã của bạn, người ta sẽ cho rằng bạn đang nhắm mục tiêu một trình duyệt hiện đại. Tôi sẽ đề nghị sử dụng 'Object.defineProperty' để mở rộng' Array.prototype'. (và thử nghiệm rằng phương thức không tồn tại trước tiên). Bạn thậm chí có thể làm cho mã chung chung hơn để làm việc '(gọi/áp dụng)' với các đối tượng khác. – Xotic750